Мемнотация memnotationwiki https://memnotation.miraheze.org/wiki/%D0%97%D0%B0%D0%B3%D0%BB%D0%B0%D0%B2%D0%BD%D0%B0%D1%8F_%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86%D0%B0 MediaWiki 1.42.1 first-letter Медиа Служебная Обсуждение Участник Обсуждение участника Мемнотация вики Мемнотация вики talk Файл Обсуждение файла MediaWiki Обсуждение MediaWiki Шаблон Обсуждение шаблона Справка Обсуждение справки Категория Обсуждение категории Модуль Обсуждение модуля Шаблон:!- 10 266 693 2008-06-07T11:54:44Z ruwiki>Alex Spade 0 -- удаляемый шаблон, ивики и категорию в документацию wikitext text/x-wiki |-<noinclude> {{doc}} <!-- Пожалуйста, добавляйте категории и интервики на страницу документации! --></noinclude> 4f45a1a9fb060eda6d4afb6850044503035d52bd Шаблон:Хх 10 260 681 2008-06-07T15:42:39Z ruwiki>Alex Spade 0 wikitext text/x-wiki [[<noinclude> {{doc}} <!-- Пожалуйста, добавляйте категории и интервики на страницу документации! --></noinclude> c18d284eaccac8b03717d7977a4bd795d3ad7f3c Шаблон:Categorytree 10 305 771 2011-02-01T03:15:33Z ruwiki>Artem Korzhimanov 0 [[ВП:←|←]] [[ВП:Перенаправления|Перенаправление]] на «[[Шаблон:Дерево категорий]]» wikitext text/x-wiki #REDIRECT [[Шаблон:Дерево категорий]] dbb44c74e7e2d0a61716eb7c903a7ecef6d38d15 Шаблон:Str len 10 166 374 2013-03-14T14:34:59Z ruwiki>DR 0 wikitext text/x-wiki {{{{{|safesubst:}}}#invoke:String|len|s={{{1|}}}}}<noinclude> {{doc}} <!-- Add categories and interwikis to the /doc subpage, not here! --> </noinclude> 95f10258d5214440d2706952656564f216c2e4cc Шаблон:Str rep 10 136 314 2015-02-28T09:38:11Z ruwiki>Rubinbot II 0 Защищена Шаблон:Str rep: Top used templates to be protected ([Редактирование=только администраторы] (бессрочно) [Переименование=только администраторы] (бессро wikitext text/x-wiki <includeonly>{{{{{|safesubst:}}}#invoke:String|replace|source={{{1}}}|{{{2}}}|{{{3}}}|{{{4|1}}}}}</includeonly><noinclude>{{doc}}</noinclude> c75032f150c372324c69a6f62ff4ab1492ad4cfa Шаблон:Lang-fi 10 181 404 2015-06-22T08:43:43Z ruwiki>DimaABot 0 Бот: удаление категории по запросу на [[ВП:РДБ]] wikitext text/x-wiki [[финский язык|фин.]] {{langi|fi|{{{1}}}}}<noinclude>{{doc|Lang/doc}} </noinclude> 16ac91b8e1e294e7687d57c0757c178f9662581c Модуль:Namespace detect/data 828 76 124 2015-06-27T21:11:34Z ruwiki>Draa kul 0 Защищена Модуль:Namespace detect/data: критический шаблон ([Редактирование=только администраторы] (бессрочно) [Переименование=только администрато… Scribunto text/plain -------------------------------------------------------------------------------- -- Namespace detect data -- -- This module holds data for [[Module:Namespace detect]] to be loaded per -- -- page, rather than per #invoke, for performance reasons. -- -------------------------------------------------------------------------------- local cfg = require('Module:Namespace detect/config') local function addKey(t, key, defaultKey) if key ~= defaultKey then t[#t + 1] = key end end -- Get a table of parameters to query for each default parameter name. -- This allows wikis to customise parameter names in the cfg table while -- ensuring that default parameter names will always work. The cfg table -- values can be added as a string, or as an array of strings. local defaultKeys = { 'main', 'talk', 'other', 'subjectns', 'demospace', 'demopage' } local argKeys = {} for i, defaultKey in ipairs(defaultKeys) do argKeys[defaultKey] = {defaultKey} end for defaultKey, t in pairs(argKeys) do local cfgValue = cfg[defaultKey] local cfgValueType = type(cfgValue) if cfgValueType == 'string' then addKey(t, cfgValue, defaultKey) elseif cfgValueType == 'table' then for i, key in ipairs(cfgValue) do addKey(t, key, defaultKey) end end cfg[defaultKey] = nil -- Free the cfg value as we don't need it any more. end local function getParamMappings() --[[ -- Returns a table of how parameter names map to namespace names. The keys -- are the actual namespace names, in lower case, and the values are the -- possible parameter names for that namespace, also in lower case. The -- table entries are structured like this: -- { -- [''] = {'main'}, -- ['wikipedia'] = {'wikipedia', 'project', 'wp'}, -- ... -- } --]] local mappings = {} local mainNsName = mw.site.subjectNamespaces[0].name mainNsName = mw.ustring.lower(mainNsName) mappings[mainNsName] = mw.clone(argKeys.main) mappings['talk'] = mw.clone(argKeys.talk) for nsid, ns in pairs(mw.site.subjectNamespaces) do if nsid ~= 0 then -- Exclude main namespace. local nsname = mw.ustring.lower(ns.name) local canonicalName = mw.ustring.lower(ns.canonicalName) mappings[nsname] = {nsname} if canonicalName ~= nsname then table.insert(mappings[nsname], canonicalName) end for _, alias in ipairs(ns.aliases) do table.insert(mappings[nsname], mw.ustring.lower(alias)) end end end return mappings end return { argKeys = argKeys, cfg = cfg, mappings = getParamMappings() } d224f42a258bc308ef3ad8cc8686cd7a4f47d005 Модуль:Namespace detect/config 828 77 126 2015-06-27T21:11:46Z ruwiki>Draa kul 0 Защищена Модуль:Namespace detect/config: критический шаблон ([Редактирование=только администраторы] (бессрочно) [Переименование=только администрат… Scribunto text/plain -------------------------------------------------------------------------------- -- Namespace detect configuration data -- -- -- -- This module stores configuration data for Module:Namespace detect. Here -- -- you can localise the module to your wiki's language. -- -- -- -- To activate a configuration item, you need to uncomment it. This means -- -- that you need to remove the text "-- " at the start of the line. -- -------------------------------------------------------------------------------- local cfg = {} -- Don't edit this line. -------------------------------------------------------------------------------- -- Parameter names -- -- These configuration items specify custom parameter names. Values added -- -- here will work in addition to the default English parameter names. -- -- To add one extra name, you can use this format: -- -- -- -- cfg.foo = 'parameter name' -- -- -- -- To add multiple names, you can use this format: -- -- -- -- cfg.foo = {'parameter name 1', 'parameter name 2', 'parameter name 3'} -- -------------------------------------------------------------------------------- ---- This parameter displays content for the main namespace: -- cfg.main = 'main' ---- This parameter displays in talk namespaces: -- cfg.talk = 'talk' ---- This parameter displays content for "other" namespaces (namespaces for which ---- parameters have not been specified): -- cfg.other = 'other' ---- This parameter makes talk pages behave as though they are the corresponding ---- subject namespace. Note that this parameter is used with [[Module:Yesno]]. ---- Edit that module to change the default values of "yes", "no", etc. -- cfg.subjectns = 'subjectns' ---- This parameter sets a demonstration namespace: -- cfg.demospace = 'demospace' ---- This parameter sets a specific page to compare: cfg.demopage = 'page' -------------------------------------------------------------------------------- -- Table configuration -- -- These configuration items allow customisation of the "table" function, -- -- used to generate a table of possible parameters in the module -- -- documentation. -- -------------------------------------------------------------------------------- ---- The header for the namespace column in the wikitable containing the list of ---- possible subject-space parameters. -- cfg.wikitableNamespaceHeader = 'Namespace' ---- The header for the wikitable containing the list of possible subject-space ---- parameters. -- cfg.wikitableAliasesHeader = 'Aliases' -------------------------------------------------------------------------------- -- End of configuration data -- -------------------------------------------------------------------------------- return cfg -- Don't edit this line. 0e4ff08d13c4b664d66b32c232deb129b77c1a56 Модуль:Color contrast/colors 828 152 346 2016-06-19T09:05:16Z ruwiki>Dima st bk 0 Защищена Модуль:Color contrast/colors: критический шаблон ([Редактирование=только администраторы] (бессрочно) [Переименование=только администрато… Scribunto text/plain return { aliceblue = 0.92880068253475, antiquewhite = 0.84646951707754, aqua = 0.7874, aquamarine = 0.8078549208338, azure = 0.97265264954166, beige = 0.8988459998705, bisque = 0.80732327372979, black = 0, blanchedalmond = 0.85084439608156, blue = 0.0722, blueviolet = 0.12622014321946, brown = 0.098224287876511, burlywood = 0.51559844533893, cadetblue = 0.29424681085422, chartreuse = 0.76032025902623, chocolate = 0.23898526114557, coral = 0.37017930872924, cornflowerblue = 0.30318641994179, cornsilk = 0.93562110372965, crimson = 0.16042199953026, cyan = 0.7874, darkblue = 0.018640801980939, darkcyan = 0.20329317839046, darkgoldenrod = 0.27264703559993, darkgray = 0.39675523072563, darkgreen = 0.091143429047575, darkgrey = 0.39675523072563, darkkhaki = 0.45747326349994, darkmagenta = 0.07353047651207, darkolivegreen = 0.12651920884889, darkorange = 0.40016167026524, darkorchid = 0.13413142174857, darkred = 0.054889674531132, darksalmon = 0.40541471563381, darkseagreen = 0.43789249325969, darkslateblue = 0.065792846227988, darkslategray = 0.067608151928044, darkslategrey = 0.067608151928044, darkturquoise = 0.4874606277449, darkviolet = 0.10999048339343, deeppink = 0.23866895828276, deepskyblue = 0.44481603395575, dimgray = 0.14126329114027, dimgrey = 0.14126329114027, dodgerblue = 0.27442536991456, firebrick = 0.10724525535015, floralwhite = 0.95922484825004, forestgreen = 0.18920812076002, fuchsia = 0.2848, gainsboro = 0.71569350050648, ghostwhite = 0.94311261886323, gold = 0.69860877428159, goldenrod = 0.41919977809569, gray = 0.2158605001139, green = 0.15438342968146, greenyellow = 0.80609472611453, grey = 0.2158605001139, honeydew = 0.96336535554782, hotpink = 0.34658438169715, indianred = 0.21406134963884, indigo = 0.03107561486337, ivory = 0.99071270600615, khaki = 0.77012343394121, lavender = 0.80318750514521, lavenderblush = 0.90172748631046, lawngreen = 0.73905893124963, lemonchiffon = 0.94038992245622, lightblue = 0.63709141280807, lightcoral = 0.35522120733135, lightcyan = 0.94587293494829, lightgoldenrodyellow = 0.93348351018297, lightgray = 0.65140563741982, lightgreen = 0.69091979956865, lightgrey = 0.65140563741982, lightpink = 0.58566152734898, lightsalmon = 0.4780675225206, lightseagreen = 0.35050145117042, lightskyblue = 0.56195637618331, lightslategray = 0.23830165007287, lightslategrey = 0.23830165007287, lightsteelblue = 0.53983888284666, lightyellow = 0.98161818392882, lime = 0.7152, limegreen = 0.44571042246098, linen = 0.88357340984379, magenta = 0.2848, maroon = 0.045891942324215, mediumaquamarine = 0.49389703310801, mediumblue = 0.044077780212328, mediumorchid = 0.21639251153773, mediumpurple = 0.22905858091648, mediumseagreen = 0.34393112338131, mediumslateblue = 0.20284629471622, mediumspringgreen = 0.70704308194184, mediumturquoise = 0.5133827926448, mediumvioletred = 0.14371899849357, midnightblue = 0.02071786635086, mintcream = 0.97834604947588, mistyrose = 0.82183047859185, moccasin = 0.80083000991567, navajowhite = 0.76519682342785, navy = 0.015585128108224, oldlace = 0.91900633405549, olive = 0.20027537200568, olivedrab = 0.22593150951929, orange = 0.4817026703631, orangered = 0.25516243753416, orchid = 0.31348806761439, palegoldenrod = 0.78792647887614, palegreen = 0.77936759006353, paleturquoise = 0.76436077921714, palevioletred = 0.28754994117889, papayawhip = 0.87797100199835, peachpuff = 0.74905589878251, peru = 0.30113074877936, pink = 0.63271070702466, plum = 0.45734221587969, powderblue = 0.68254586500605, purple = 0.061477070432439, rebeccapurple = 0.07492341159447, red = 0.2126, rosybrown = 0.32319457649407, royalblue = 0.16663210743188, saddlebrown = 0.097922285020521, salmon = 0.36977241527596, sandybrown = 0.46628543696283, seagreen = 0.19734199706275, seashell = 0.92737862206922, sienna = 0.13697631337098, silver = 0.52711512570581, skyblue = 0.55291668518184, slateblue = 0.14784278062136, slategray = 0.20896704076536, slategrey = 0.20896704076536, snow = 0.96533341834849, springgreen = 0.73052306068529, steelblue = 0.20562642207625, tan = 0.48237604163921, teal = 0.16996855778968, thistle = 0.56818401093733, tomato = 0.30638612719415, turquoise = 0.5895536427578, violet = 0.40315452986676, wheat = 0.74909702820482, white = 1, whitesmoke = 0.91309865179342, yellow = 0.9278, yellowgreen = 0.50762957208707, } 6ae47fdb24de4eed5ec26d203faf5341a388987b Шаблон:Wikidata/p570 10 271 703 2016-07-12T17:40:22Z ruwiki>Putnik 0 скрытие значения из Викиданных при помощи «-» wikitext text/x-wiki {{#switch:{{{1|}}}|-=|={{#invoke:Wikidata|formatStatements|property=p570|claim-module=Wikidata/date|claim-function=formatDateOfDeathClaim|nocat={{{nocat|}}}{{NAMESPACE}}}}|{{#invoke:Infocards|dateOfDeath|{{{2|}}}|{{{1|}}}|nocat={{{nocat|}}}{{NAMESPACE}}}}}}<noinclude>{{doc}}</noinclude> a51af6d007d156cfeacb13a0a4a7471da7d4ed22 Шаблон:Население государства 10 180 402 2016-08-16T20:27:21Z ruwiki>SandBot 0 /* top */удаление устаревшего ключа сортировки wikitext text/x-wiki <includeonly>{{#switch: {{{1}}} | Республика Южная Осетия = Население Южной Осетии{{!}}Население | Население }}</includeonly><noinclude> {{doc}} [[Категория:Шаблоны по странам]] </noinclude> e0568280ef5056e94f5f1abf1934f4188a52c35f Шаблон:Str find 10 214 476 2016-11-07T15:00:14Z ruwiki>Jack who built the house 0 последуем написанному в комментарии и перенесём категории на подстраницу wikitext text/x-wiki {{ {{{|safesubst:}}}#invoke:String|str_find|source={{{1|}}}|{{{2|}}}}}<noinclude> {{doc}} <!-- Add categories and interwikis to the /doc subpage, not here! --> </noinclude> 18d1469d30d27a82ee15fd2fb1ca12a34b5f5e87 Шаблон:Nobr 10 147 336 2016-12-02T13:15:38Z ruwiki>Jack who built the house 0 используем класс nowrap wikitext text/x-wiki <includeonly><span class="nowrap">{{{1}}}</span></includeonly><noinclude> {{doc}} <!-- Пожалуйста, добавляйте категории и интервики на страницу документации! --> </noinclude> 989c6f164ed3a8543e916c8f1746ba1ab94fb068 Шаблон:Ambox 10 193 432 2017-02-15T11:02:18Z ruwiki>Iniquity 0 теперь есть в модуле wikitext text/x-wiki {{#invoke:Message box|ambox}}{{#ifeq:{{{small}}}|left|[[Категория:Страницы, использующие малые шаблоны-сообщения]]}}<noinclude> {{doc}} <!-- Categories go on the /doc subpage, and interwikis go on Wikidata. --> </noinclude> 5345bd7c0e2430e3672a54d920abd0f0bf61dc61 Шаблон:Без уточнения 10 132 306 2017-03-12T19:54:44Z ruwiki>Jack who built the house 0 бoлee кoppeктный пaттepн; нaпpимep, в «Haзвaниe (нeyтoчнeниe) (yтoчнeниe)» yтoчнeниeм дoлжнa cчитaтьcя тoлькo пocлeдняя чacть. вoзмoжнocть иcпол. бeз 1-гo пap. и пoдcтaн. wikitext text/x-wiki <includeonly>{{ {{{|safesubst:}}}#invoke:String|replace|{{{1|{{ {{{|safesubst:}}}PAGENAME}}}}}|^%s*(.+)%s+%b()%s*$|%1||false}}</includeonly><noinclude>{{doc}}</noinclude> 1fcb3edb0be49656ae0f913e9a8fb4853264b480 Шаблон:Clear 10 188 420 2017-05-07T18:43:17Z ruwiki>Stjn 0 Saint Johann переименовал страницу [[Шаблон:-]] в [[Шаблон:Clear]]: более понятное (хоть и менее используемое) название wikitext text/x-wiki <div style="clear:{{{1|both}}};"></div><noinclude>{{doc}}</noinclude> 15e943687be5d8f8e27fa6cc7813bbfa85df72a9 Шаблон:- 10 189 422 2017-05-07T18:43:17Z ruwiki>Stjn 0 Saint Johann переименовал страницу [[Шаблон:-]] в [[Шаблон:Clear]]: более понятное (хоть и менее используемое) название wikitext text/x-wiki #перенаправление [[Шаблон:Clear]] f3ec5262c8fab1ae984101008632fb9c091fb431 Шаблон:Вложенные кавычки 10 292 745 2017-05-14T16:34:35Z ruwiki>Draa kul 0 Защитил «[[Шаблон:Вложенные кавычки]]»: критический шаблон ([Редактирование=только администраторы] (бессрочно) [Переименование=только адм… wikitext text/x-wiki {{replace | {{#invoke:string|replace<!-- -->| {{#invoke:string|replace<!-- -->| {{#invoke:string|replace<!-- -->| {{#invoke:string|replace<!-- -->| {{{1|}}} | pattern = %[%[(.?[^%]{{!}}]-)«(.[^«»]-)»(.?[^%]{{!}}]-){{!}} | replace = {{хх}}%1<<%2>>%3{{!}} | plain = false<!-- -->}} | pattern = %[%[(.?[^%]{{!}}]-)«(.[^«»]-)»(.?[^%[{{!}}]-)%]%] | replace = [[%1<<%2>>%3{{!}}%1«%2»%3]] | plain = false<!-- -->}} | pattern = «(.[^«»]-)» | replace = „%1“ | plain = false<!-- -->}} | pattern = <<(.[^<>]-)>> | replace = «%1» | plain = false<!-- -->}}}}<noinclude>{{doc}}</noinclude> 48611a5cc8c8ac357e4b2a083c1845c15462160e Шаблон:Delink 10 263 687 2017-08-01T19:23:44Z ruwiki>Q-bit array 0 Защитил «[[Шаблон:Delink]]»: критический шаблон ([Редактирование=только администраторы] (бессрочно) [Переименование=только администраторы] (б… wikitext text/x-wiki {{<includeonly>safesubst:</includeonly>#invoke:delink|delink}}<noinclude> {{doc}} </noinclude> dbac86e53b946e60d5b6236381e8c31858e79ee5 Шаблон:Карточка/название 10 130 302 2017-08-01T19:26:37Z ruwiki>Q-bit array 0 Защитил «[[Шаблон:Карточка/название]]»: критический шаблон ([Редактирование=только администраторы] (бессрочно) [Переименование=только адм… wikitext text/x-wiki {{#if:{{{1|}}}|{{{1}}}|{{без уточнения|{{PAGENAME}}}}}}<noinclude> {{doc}} </noinclude> 110edc6d8286f120a048863c68371720bd4e65ca Шаблон:Карточка/имя 10 267 695 2017-08-01T19:26:40Z ruwiki>Q-bit array 0 Защитил «[[Шаблон:Карточка/имя]]»: критический шаблон ([Редактирование=только администраторы] (бессрочно) [Переименование=только админист… wikitext text/x-wiki {{#if:{{{1|}}}|{{{1}}}|{{сначала имя|{{PAGENAME}}}}}}<noinclude> {{doc}} </noinclude> c2c97d1196f5c50a2ec1aa866cd4004526a32383 Модуль:Category handler/config 828 70 112 2017-08-01T19:26:42Z ruwiki>Q-bit array 0 Защитил «[[Модуль:Category handler/config]]»: критический шаблон ([Редактирование=только администраторы] (бессрочно) [Переименование=только админист… Scribunto text/plain -------------------------------------------------------------------------------- -- [[Module:Category handler]] configuration data -- -- Language-specific parameter names and values can be set here. -- -- For blacklist config, see [[Module:Category handler/blacklist]]. -- -------------------------------------------------------------------------------- local cfg = {} -- Don't edit this line. -------------------------------------------------------------------------------- -- Start configuration data -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Parameter names -- -- These configuration items specify custom parameter names. -- -- To add one extra name, you can use this format: -- -- -- -- foo = 'parameter name', -- -- -- -- To add multiple names, you can use this format: -- -- -- -- foo = {'parameter name 1', 'parameter name 2', 'parameter name 3'}, -- -------------------------------------------------------------------------------- cfg.parameters = { -- The nocat and categories parameter suppress -- categorisation. They are used with Module:Yesno, and work as follows: -- -- cfg.nocat: -- Result of yesno() Effect -- true Categorisation is suppressed -- false Categorisation is allowed, and -- the blacklist check is skipped -- nil Categorisation is allowed -- -- cfg.categories: -- Result of yesno() Effect -- true Categorisation is allowed, and -- the blacklist check is skipped -- false Categorisation is suppressed -- nil Categorisation is allowed nocat = 'nocat', categories = 'categories', -- The parameter name for the legacy "category2" parameter. This skips the -- blacklist if set to the cfg.category2Yes value, and suppresses -- categorisation if present but equal to anything other than -- cfg.category2Yes or cfg.category2Negative. category2 = 'category2', -- cfg.subpage is the parameter name to specify how to behave on subpages. subpage = 'subpage', -- The parameter for data to return in all namespaces. all = 'all', -- The parameter name for data to return if no data is specified for the -- namespace that is detected. other = 'other', -- The parameter name used to specify a page other than the current page; -- used for testing and demonstration. demopage = 'page', } -------------------------------------------------------------------------------- -- Parameter values -- -- These are set values that can be used with certain parameters. Only one -- -- value can be specified, like this: -- -- -- -- cfg.foo = 'value name' -- -- -------------------------------------------------------------------------------- -- The following settings are used with the cfg.category2 parameter. Setting -- cfg.category2 to cfg.category2Yes skips the blacklist, and if cfg.category2 -- is present but equal to anything other than cfg.category2Yes or -- cfg.category2Negative then it supresses cateogrisation. cfg.category2Yes = 'yes' cfg.category2Negative = '¬' -- The following settings are used with the cfg.subpage parameter. -- cfg.subpageNo is the value to specify to not categorise on subpages; -- cfg.subpageOnly is the value to specify to only categorise on subpages. cfg.subpageNo = 'no' cfg.subpageOnly = 'only' -------------------------------------------------------------------------------- -- Default namespaces -- -- This is a table of namespaces to categorise by default. The keys are the -- -- namespace numbers. -- -------------------------------------------------------------------------------- cfg.defaultNamespaces = { [ 0] = true, -- main [ 6] = true, -- file [ 12] = true, -- help [ 14] = true, -- category [100] = true, -- portal [108] = true, -- book } -------------------------------------------------------------------------------- -- Wrappers -- -- This is a wrapper template or a list of wrapper templates to be passed to -- -- [[Module:Arguments]]. -- -------------------------------------------------------------------------------- cfg.wrappers = 'Template:Category handler' -------------------------------------------------------------------------------- -- End configuration data -- -------------------------------------------------------------------------------- return cfg -- Don't edit this line. 373cd107b13a5b00e6a1b7e66a749f12502c849d Модуль:Category handler/blacklist 828 75 122 2017-08-01T19:26:43Z ruwiki>Q-bit array 0 Защитил «[[Модуль:Category handler/blacklist]]»: критический шаблон ([Редактирование=только администраторы] (бессрочно) [Переименование=только админис… Scribunto text/plain -- This module contains the blacklist used by [[Module:Category handler]]. -- Pages that match Lua patterns in this list will not be categorised unless -- categorisation is explicitly requested. return { '^Main Page$', -- don't categorise the main page. -- Don't categorise the following pages or their subpages. -- "%f[/\0]" matches if the next character is "/" or the end of the string. '^Wikipedia:Cascade%-protected items%f[/\0]', '^User:UBX%f[/\0]', -- The userbox "template" space. '^User talk:UBX%f[/\0]', -- Don't categorise subpages of these pages, but allow -- categorisation of the base page. '^Wikipedia:Template messages/.*$', '/[aA]rchive' -- Don't categorise archives. } c84948ad9808d5d323408d5d10d5652f748a0550 Модуль:Category handler 828 31 414 2017-08-01T19:26:45Z ruwiki>Q-bit array 0 Защитил «[[Модуль:Category handler]]»: критический шаблон ([Редактирование=только администраторы] (бессрочно) [Переименование=только администрато… Scribunto text/plain -------------------------------------------------------------------------------- -- -- -- CATEGORY HANDLER -- -- -- -- This module implements the {{category handler}} template in Lua, -- -- with a few improvements: all namespaces and all namespace aliases -- -- are supported, and namespace names are detected automatically for -- -- the local wiki. This module requires [[Module:Namespace detect]] -- -- and [[Module:Yesno]] to be available on the local wiki. It can be -- -- configured for different wikis by altering the values in -- -- [[Module:Category handler/config]], and pages can be blacklisted -- -- from categorisation by using [[Module:Category handler/blacklist]]. -- -- -- -------------------------------------------------------------------------------- -- Load required modules local yesno = require('Module:Yesno') -- Lazily load things we don't always need local mShared, mappings local p = {} -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function trimWhitespace(s, removeBlanks) if type(s) ~= 'string' then return s end s = s:match('^%s*(.-)%s*$') if removeBlanks then if s ~= '' then return s else return nil end else return s end end -------------------------------------------------------------------------------- -- CategoryHandler class -------------------------------------------------------------------------------- local CategoryHandler = {} CategoryHandler.__index = CategoryHandler function CategoryHandler.new(data, args) local obj = setmetatable({ _data = data, _args = args }, CategoryHandler) -- Set the title object do local pagename = obj:parameter('demopage') local success, titleObj if pagename then success, titleObj = pcall(mw.title.new, pagename) end if success and titleObj then obj.title = titleObj if titleObj == mw.title.getCurrentTitle() then obj._usesCurrentTitle = true end else obj.title = mw.title.getCurrentTitle() obj._usesCurrentTitle = true end end -- Set suppression parameter values for _, key in ipairs{'nocat', 'categories'} do local value = obj:parameter(key) value = trimWhitespace(value, true) obj['_' .. key] = yesno(value) end do local subpage = obj:parameter('subpage') local category2 = obj:parameter('category2') if type(subpage) == 'string' then subpage = mw.ustring.lower(subpage) end if type(category2) == 'string' then subpage = mw.ustring.lower(category2) end obj._subpage = trimWhitespace(subpage, true) obj._category2 = trimWhitespace(category2) -- don't remove blank values end return obj end function CategoryHandler:parameter(key) local parameterNames = self._data.parameters[key] local pntype = type(parameterNames) if pntype == 'string' or pntype == 'number' then return self._args[parameterNames] elseif pntype == 'table' then for _, name in ipairs(parameterNames) do local value = self._args[name] if value ~= nil then return value end end return nil else error(string.format( 'invalid config key "%s"', tostring(key) ), 2) end end function CategoryHandler:isSuppressedByArguments() return -- See if a category suppression argument has been set. self._nocat == true or self._categories == false or ( self._category2 and self._category2 ~= self._data.category2Yes and self._category2 ~= self._data.category2Negative ) -- Check whether we are on a subpage, and see if categories are -- suppressed based on our subpage status. or self._subpage == self._data.subpageNo and self.title.isSubpage or self._subpage == self._data.subpageOnly and not self.title.isSubpage end function CategoryHandler:shouldSkipBlacklistCheck() -- Check whether the category suppression arguments indicate we -- should skip the blacklist check. return self._nocat == false or self._categories == true or self._category2 == self._data.category2Yes end function CategoryHandler:matchesBlacklist() if self._usesCurrentTitle then return self._data.currentTitleMatchesBlacklist else mShared = mShared or require('Module:Category handler/shared') return mShared.matchesBlacklist( self.title.prefixedText, mw.loadData('Module:Category handler/blacklist') ) end end function CategoryHandler:isSuppressed() -- Find if categories are suppressed by either the arguments or by -- matching the blacklist. return self:isSuppressedByArguments() or not self:shouldSkipBlacklistCheck() and self:matchesBlacklist() end function CategoryHandler:getNamespaceParameters() if self._usesCurrentTitle then return self._data.currentTitleNamespaceParameters else if not mappings then mShared = mShared or require('Module:Category handler/shared') mappings = mShared.getParamMappings(true) -- gets mappings with mw.loadData end return mShared.getNamespaceParameters( self.title, mappings ) end end function CategoryHandler:namespaceParametersExist() -- Find whether any namespace parameters have been specified. -- We use the order "all" --> namespace params --> "other" as this is what -- the old template did. if self:parameter('all') then return true end if not mappings then mShared = mShared or require('Module:Category handler/shared') mappings = mShared.getParamMappings(true) -- gets mappings with mw.loadData end for ns, params in pairs(mappings) do for i, param in ipairs(params) do if self._args[param] then return true end end end if self:parameter('other') then return true end return false end function CategoryHandler:getCategories() local params = self:getNamespaceParameters() local nsCategory for i, param in ipairs(params) do local value = self._args[param] if value ~= nil then nsCategory = value break end end if nsCategory ~= nil or self:namespaceParametersExist() then -- Namespace parameters exist - advanced usage. if nsCategory == nil then nsCategory = self:parameter('other') end local ret = {self:parameter('all')} local numParam = tonumber(nsCategory) if numParam and numParam >= 1 and math.floor(numParam) == numParam then -- nsCategory is an integer ret[#ret + 1] = self._args[numParam] else ret[#ret + 1] = nsCategory end if #ret < 1 then return nil else return table.concat(ret) end elseif self._data.defaultNamespaces[self.title.namespace] then -- Namespace parameters don't exist, simple usage. return self._args[1] end return nil end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- Used for testing purposes. return { CategoryHandler = CategoryHandler } end function p._main(args, data) data = data or mw.loadData('Module:Category handler/data') local handler = CategoryHandler.new(data, args) if handler:isSuppressed() then return nil end return handler:getCategories() end function p.main(frame, data) data = data or mw.loadData('Module:Category handler/data') local args = require('Module:Arguments').getArgs(frame, { wrappers = data.wrappers, valueFunc = function (k, v) v = trimWhitespace(v) if type(k) == 'number' then if v ~= '' then return v else return nil end else return v end end }) return p._main(args, data) end return p b74dd63857b24904ac452429b11213f18647471f Модуль:Category handler/shared 828 74 120 2017-08-01T19:26:47Z ruwiki>Q-bit array 0 Защитил «[[Модуль:Category handler/shared]]»: критический шаблон ([Редактирование=только администраторы] (бессрочно) [Переименование=только админист… Scribunto text/plain -- This module contains shared functions used by [[Module:Category handler]] -- and its submodules. local p = {} function p.matchesBlacklist(page, blacklist) for i, pattern in ipairs(blacklist) do local match = mw.ustring.match(page, pattern) if match then return true end end return false end function p.getParamMappings(useLoadData) local dataPage = 'Module:Namespace detect/data' if useLoadData then return mw.loadData(dataPage).mappings else return require(dataPage).mappings end end function p.getNamespaceParameters(titleObj, mappings) -- We don't use title.nsText for the namespace name because it adds -- underscores. local mappingsKey if titleObj.isTalkPage then mappingsKey = 'talk' else mappingsKey = mw.site.namespaces[titleObj.namespace].name end mappingsKey = mw.ustring.lower(mappingsKey) return mappings[mappingsKey] or {} end return p d2d5de1a031e6ce97c242cbfa8afe7a92cb9eca5 Модуль:Category handler/data 828 69 110 2017-08-01T19:26:49Z ruwiki>Q-bit array 0 Защитил «[[Модуль:Category handler/data]]»: критический шаблон ([Редактирование=только администраторы] (бессрочно) [Переименование=только администр… Scribunto text/plain -- This module assembles data to be passed to [[Module:Category handler]] using -- mw.loadData. This includes the configuration data and whether the current -- page matches the title blacklist. local data = require('Module:Category handler/config') local mShared = require('Module:Category handler/shared') local blacklist = require('Module:Category handler/blacklist') local title = mw.title.getCurrentTitle() data.currentTitleMatchesBlacklist = mShared.matchesBlacklist( title.prefixedText, blacklist ) data.currentTitleNamespaceParameters = mShared.getNamespaceParameters( title, mShared.getParamMappings() ) return data abbc68048ff698e88dda06b64ecf384bbf583120 Шаблон:(! 10 254 668 2017-08-01T19:30:34Z ruwiki>Q-bit array 0 Защитил «[[Шаблон:(!]]»: критический шаблон ([Редактирование=только администраторы] (бессрочно) [Переименование=только администраторы] (бес… wikitext text/x-wiki <includeonly>{|</includeonly><noinclude><nowiki>{|</nowiki>{{Doc}} </noinclude> fc286c1b614a7c93a17dd6f17f52dba12b86e363 Шаблон:!) 10 255 670 2017-08-01T19:30:40Z ruwiki>Q-bit array 0 Изменил уровень защиты «[[Шаблон:!)]]»: критический шаблон ([Редактирование=только администраторы] (бессрочно) [Переименование=только админ… wikitext text/x-wiki |}<noinclude>{{Doc}} </noinclude> c1895c0eccb60664bc4f2bd850d909b3c65739c3 Шаблон:Yesno 10 131 304 2017-08-01T19:30:50Z ruwiki>Q-bit array 0 Защитил «[[Шаблон:Yesno]]»: критический шаблон ([Редактирование=только администраторы] (бессрочно) [Переименование=только администраторы] (бе… wikitext text/x-wiki {{<includeonly>safesubst:</includeonly>#switch: {{<includeonly>safesubst:</includeonly>lc: {{{1|¬}}} }} |no |n |нет |false |0 = {{{no|<!-- null -->}}} | = {{{blank|{{{no|<!-- null -->}}}}}} |¬ = {{{¬|}}} |yes |y |да |true |1 = {{{yes|yes}}} |#default = {{{def|{{{yes|yes}}}}}} }}<noinclude> {{Documentation}} </noinclude> 4e236854c477d07a225c2ab6c016c389b133e8d3 Модуль:URL 828 265 691 2017-09-18T16:34:08Z ruwiki>Jack who built the house 0 уточнение категоризации Scribunto text/plain function startsWith( source, substring ) if mw.ustring.len( substring ) > mw.ustring.len( source ) then return false end return mw.ustring.sub( source, 1, mw.ustring.len( substring ) ) == substring end p = {} function formatUrlImpl( source, title, length ) local scheme, host, path local postfix = '' local arg1, arg2 = source, title local isTestPage = mw.title.getCurrentTitle().prefixedText == 'Модуль:URL' -- Две квадратные скобки подряд — [[вики-ссылка]] вместо [ссылки] — возвращаем вход как есть. if string.find( arg1, "[[", 1, true ) then local result = arg1 if not isTestPage then result = result .. '[[Категория:Википедия:Статьи с вики-ссылкой, переданной в Модуль:URL]]' if arg2 then -- Если есть arg2, а мы распарсить ссылку не смогли, и значит заменить title не сможем корректно, это есть ошибка. result = result .. '[[Категория:Википедия:Статьи с ошибочной работой Модуль:URL]]' end end return result end -- Более одной квадратной скобки — скорее всего, задано более одного URL — тоже возвращаем как есть. if select(2, string.gsub( arg1, "%[", "" )) > 1 then local result = arg1 if not isTestPage then result = result .. '[[Категория:Википедия:Статьи со сложным входом в Модуль:URL]]' if arg2 then -- Если есть arg2, а мы распарсить ссылку не смогли, и значит заменить title не сможем корректно, это есть ошибка. result = result .. '[[Категория:Википедия:Статьи с ошибочной работой Модуль:URL]]' end end return result end source = mw.text.trim( source, "%[%] " ) local titleDelimeterPosition = mw.ustring.find( source, " ", 1 ) if titleDelimeterPosition then if not title or title == "" then title = mw.ustring.sub( source, titleDelimeterPosition + 1 ) local postfixDelimeterPosition = mw.ustring.find( title, "%]", 1 ) if postfixDelimeterPosition then postfix = mw.ustring.sub( title, postfixDelimeterPosition + 1 ) title = mw.ustring.sub( title, 1, postfixDelimeterPosition - 1 ) end end source = mw.ustring.sub( source, 1, titleDelimeterPosition - 1 ) end local hostStartPosition local schemeDelimeterPosition = mw.ustring.find( source, "://", 1, true ) if schemeDelimeterPosition then scheme = mw.ustring.sub( source, 1, schemeDelimeterPosition + 2) hostStartPosition = schemeDelimeterPosition + 3 elseif mw.ustring.find( source, "^//", 1 ) then scheme = "//" hostStartPosition = 3 elseif mw.ustring.find( source, "^mailto:", 1 ) then scheme = "mailto:" hostStartPosition = 8 elseif mw.ustring.find( source, "@", 1 ) then scheme = "mailto:" source = scheme .. source hostStartPosition = 8 else scheme = "http://" source = scheme .. source hostStartPosition = 8 end if title then local finds = mw.ustring.find( arg1, "[", 1, true ) if titleDelimeterPosition and finds and finds > titleDelimeterPosition + 1 then -- Если titleDelimeterPosition промазал мимо скобки и нашел пробел раньше неё, к примеру "a [b c]", -- то свернуть всю нашу хиромантию и выдать первый аргумент без изменений. if arg2 == nil then return arg1 .. (isTestPage and '' or '[[Категория:Википедия:Статьи со сложным входом в Модуль:URL]]') -- Если есть arg2, а мы распарсить ссылку не смогли, и значит заменить title не сможем корректно, это есть ошибка. -- С другой стороны, если arg2 нет, а arg1 очень сложный, то возможно это нормальный ход вещей, -- и на вход в модуль дана уже очень сильно оформленная ссылка. else return arg1 .. (isTestPage and '' or '[[Категория:Википедия:Статьи с ошибочной работой Модуль:URL]]') end end return '[' .. source .. ' ' .. title .. ']' .. postfix end local hostDelimeterPosition = mw.ustring.find( source, "/", hostStartPosition, true ) if hostDelimeterPosition then host = mw.ustring.sub( source, hostStartPosition, hostDelimeterPosition - 1 ) if hostDelimeterPosition == mw.ustring.len( source ) then path = nil else path = mw.ustring.sub( source, hostDelimeterPosition + 1 ) end else host = mw.ustring.sub( source, hostStartPosition ) end -- post-split format options if startsWith( host, 'www.' ) then host = mw.ustring.sub( host, 5 ) end host = mw.language.new( 'en' ):lc( host ) if path and path ~= '' and path ~= '/' then local title = host .. '/' .. path if length and #title > length then title = host .. '/' .. mw.ustring.sub( path, 1, length - #title - 2 ) .. '…' end return '[' .. source .. ' ' .. title .. ']' .. postfix else return '[' .. source .. ' ' .. host .. ']' .. postfix end end function p.formatUrl( frame ) local url = frame.args[1] or '' local title = frame.args[2] or '' local length = frame.args['length'] and tonumber( frame.args['length'] ) url = mw.text.trim( url ) title = mw.text.trim( title ) if url == '' then return nil end if title == '' then title = nil end return formatUrlImpl( url, title, length ) end function p.formatUrlSingle( context, options, url ) url = mw.text.trim( url ) if url == '' then return nil end local title = nil if ( options['text'] and options['text'] ~= '' ) then title = options['text'] end local length = options['length'] and tonumber( options['length'] ) return formatUrlImpl( url, title, length ) end return p a991f879e135a472238c7f589e8d20d92a856d4d Шаблон:Langi 10 123 288 2017-10-14T07:25:47Z ruwiki>Jack who built the house 0 → [[/doc]] wikitext text/x-wiki <span lang="{{{1}}}" xml:lang="{{{1}}}" style="font-style:italic;">{{{2}}}</span><noinclude>{{doc}}</noinclude> 7bb9f9098c88e770b982402adf30a3bbf645aa4b Шаблон:Lang-sv 10 177 396 2017-12-10T06:47:12Z ruwiki>Dima st bk 0 langi wikitext text/x-wiki [[шведский язык|швед.]] {{langi|sv|{{{1}}}}}<noinclude>{{doc|Lang/doc}} </noinclude> c4b5e81c6405972dcea4cc26ab77e99e9bd2021f Модуль:Arguments 828 124 290 2018-01-12T21:01:04Z ruwiki>Grain of sand 0 sandbox → песочница Scribunto text/plain -- This module provides easy processing of arguments passed to Scribunto from -- #invoke. It is intended for use by other Lua modules, and should not be -- called from #invoke directly. local libraryUtil = require('libraryUtil') local checkType = libraryUtil.checkType local arguments = {} -- Generate four different tidyVal functions, so that we don't have to check the -- options every time we call it. local function tidyValDefault(key, val) if type(val) == 'string' then val = val:match('^%s*(.-)%s*$') if val == '' then return nil else return val end else return val end end local function tidyValTrimOnly(key, val) if type(val) == 'string' then return val:match('^%s*(.-)%s*$') else return val end end local function tidyValRemoveBlanksOnly(key, val) if type(val) == 'string' then if val:find('%S') then return val else return nil end else return val end end local function tidyValNoChange(key, val) return val end local function matchesTitle(given, title) local tp = type( given ) return (tp == 'string' or tp == 'number') and mw.title.new( given ).prefixedText == title end local translate_mt = { __index = function(t, k) return k end } function arguments.getArgs(frame, options) checkType('getArgs', 1, frame, 'table', true) checkType('getArgs', 2, options, 'table', true) frame = frame or {} options = options or {} --[[ -- Set up argument translation. --]] options.translate = options.translate or {} if getmetatable(options.translate) == nil then setmetatable(options.translate, translate_mt) end if options.backtranslate == nil then options.backtranslate = {} for k,v in pairs(options.translate) do options.backtranslate[v] = k end end if options.backtranslate and getmetatable(options.backtranslate) == nil then setmetatable(options.backtranslate, { __index = function(t, k) if options.translate[k] ~= k then return nil else return k end end }) end --[[ -- Get the argument tables. If we were passed a valid frame object, get the -- frame arguments (fargs) and the parent frame arguments (pargs), depending -- on the options set and on the parent frame's availability. If we weren't -- passed a valid frame object, we are being called from another Lua module -- or from the debug console, so assume that we were passed a table of args -- directly, and assign it to a new variable (luaArgs). --]] local fargs, pargs, luaArgs if type(frame.args) == 'table' and type(frame.getParent) == 'function' then if options.wrappers then --[[ -- The wrappers option makes Module:Arguments look up arguments in -- either the frame argument table or the parent argument table, but -- not both. This means that users can use either the #invoke syntax -- or a wrapper template without the loss of performance associated -- with looking arguments up in both the frame and the parent frame. -- Module:Arguments will look up arguments in the parent frame -- if it finds the parent frame's title in options.wrapper; -- otherwise it will look up arguments in the frame object passed -- to getArgs. --]] local parent = frame:getParent() if not parent then fargs = frame.args else local title = parent:getTitle():gsub('/песочница$', '') local found = false if matchesTitle(options.wrappers, title) then found = true elseif type(options.wrappers) == 'table' then for _,v in pairs(options.wrappers) do if matchesTitle(v, title) then found = true break end end end -- We test for false specifically here so that nil (the default) acts like true. if found or options.frameOnly == false then pargs = parent.args end if not found or options.parentOnly == false then fargs = frame.args end end else -- options.wrapper isn't set, so check the other options. if not options.parentOnly then fargs = frame.args end if not options.frameOnly then local parent = frame:getParent() pargs = parent and parent.args or nil end end if options.parentFirst then fargs, pargs = pargs, fargs end else luaArgs = frame end -- Set the order of precedence of the argument tables. If the variables are -- nil, nothing will be added to the table, which is how we avoid clashes -- between the frame/parent args and the Lua args. local argTables = {fargs} argTables[#argTables + 1] = pargs argTables[#argTables + 1] = luaArgs --[[ -- Generate the tidyVal function. If it has been specified by the user, we -- use that; if not, we choose one of four functions depending on the -- options chosen. This is so that we don't have to call the options table -- every time the function is called. --]] local tidyVal = options.valueFunc if tidyVal then if type(tidyVal) ~= 'function' then error( "bad value assigned to option 'valueFunc'" .. '(function expected, got ' .. type(tidyVal) .. ')', 2 ) end elseif options.trim ~= false then if options.removeBlanks ~= false then tidyVal = tidyValDefault else tidyVal = tidyValTrimOnly end else if options.removeBlanks ~= false then tidyVal = tidyValRemoveBlanksOnly else tidyVal = tidyValNoChange end end --[[ -- Set up the args, metaArgs and nilArgs tables. args will be the one -- accessed from functions, and metaArgs will hold the actual arguments. Nil -- arguments are memoized in nilArgs, and the metatable connects all of them -- together. --]] local args, metaArgs, nilArgs, metatable = {}, {}, {}, {} setmetatable(args, metatable) local function mergeArgs(tables) --[[ -- Accepts multiple tables as input and merges their keys and values -- into one table. If a value is already present it is not overwritten; -- tables listed earlier have precedence. We are also memoizing nil -- values, which can be overwritten if they are 's' (soft). --]] for _, t in ipairs(tables) do for key, val in pairs(t) do if metaArgs[key] == nil and nilArgs[key] ~= 'h' then local tidiedVal = tidyVal(key, val) if tidiedVal == nil then nilArgs[key] = 's' else metaArgs[key] = tidiedVal end end end end end --[[ -- Define metatable behaviour. Arguments are memoized in the metaArgs table, -- and are only fetched from the argument tables once. Fetching arguments -- from the argument tables is the most resource-intensive step in this -- module, so we try and avoid it where possible. For this reason, nil -- arguments are also memoized, in the nilArgs table. Also, we keep a record -- in the metatable of when pairs and ipairs have been called, so we do not -- run pairs and ipairs on the argument tables more than once. We also do -- not run ipairs on fargs and pargs if pairs has already been run, as all -- the arguments will already have been copied over. --]] metatable.__index = function (t, key) --[[ -- Fetches an argument when the args table is indexed. First we check -- to see if the value is memoized, and if not we try and fetch it from -- the argument tables. When we check memoization, we need to check -- metaArgs before nilArgs, as both can be non-nil at the same time. -- If the argument is not present in metaArgs, we also check whether -- pairs has been run yet. If pairs has already been run, we return nil. -- This is because all the arguments will have already been copied into -- metaArgs by the mergeArgs function, meaning that any other arguments -- must be nil. --]] if type(key) == 'string' then key = options.translate[key] end local val = metaArgs[key] if val ~= nil then return val elseif metatable.donePairs or nilArgs[key] then return nil end for _, argTable in ipairs(argTables) do local argTableVal = tidyVal(key, argTable[key]) if argTableVal ~= nil then metaArgs[key] = argTableVal return argTableVal end end nilArgs[key] = 'h' return nil end metatable.__newindex = function (t, key, val) -- This function is called when a module tries to add a new value to the -- args table, or tries to change an existing value. if type(key) == 'string' then key = options.translate[key] end if options.readOnly then error( 'could not write to argument table key "' .. tostring(key) .. '"; the table is read-only', 2 ) elseif options.noOverwrite and args[key] ~= nil then error( 'could not write to argument table key "' .. tostring(key) .. '"; overwriting existing arguments is not permitted', 2 ) elseif val == nil then --[[ -- If the argument is to be overwritten with nil, we need to erase -- the value in metaArgs, so that __index, __pairs and __ipairs do -- not use a previous existing value, if present; and we also need -- to memoize the nil in nilArgs, so that the value isn't looked -- up in the argument tables if it is accessed again. --]] metaArgs[key] = nil nilArgs[key] = 'h' else metaArgs[key] = val end end local function translatenext(invariant) local k, v = next(invariant.t, invariant.k) invariant.k = k if k == nil then return nil elseif type(k) ~= 'string' or not options.backtranslate then return k, v else local backtranslate = options.backtranslate[k] if backtranslate == nil then -- Skip this one. This is a tail call, so this won't cause stack overflow return translatenext(invariant) else return backtranslate, v end end end metatable.__pairs = function () -- Called when pairs is run on the args table. if not metatable.donePairs then mergeArgs(argTables) metatable.donePairs = true end return translatenext, { t = metaArgs } end local function inext(t, i) -- This uses our __index metamethod local v = t[i + 1] if v ~= nil then return i + 1, v end end metatable.__ipairs = function (t) -- Called when ipairs is run on the args table. return inext, t, 0 end return args end return arguments e6be8dfccffa2057c3d50700f350d8d140c1dbf9 Шаблон:Join 10 150 342 2018-06-13T14:41:38Z ruwiki>Jack who built the house 0 перевод на модуль wikitext text/x-wiki {{<includeonly>safesubst:</includeonly>#invoke:Separated entries|main|separator={{{separator|}}}}}<noinclude> {{doc}} <!-- Категории — на подстраницу /doc, интервики — в Викиданные. --> </noinclude> 92bb17b5322d3ae0ceab93d4dad3d31810d47eb0 Шаблон:МестоСмерти 10 272 705 2018-06-13T20:22:03Z ruwiki>WindEwriX 0 ставить [[Ш:Категория только в статьях]] под проверкой пространства имён в шаблоне на 100к включений это мощь wikitext text/x-wiki <includeonly>{{#if:{{{3|}}}|[[{{{3}}}|{{{1}}}]]|{{#if:{{{1|}}}|[[{{{1}}}]]}}}}{{#if:{{NAMESPACE}}||{{#if:{{{1|}}}|[[Категория:Персоналии по алфавиту]][[Категория:Умершие {{#if:{{{2|}}}|{{{2}}}|в {{#ifeq:{{{1}}}|Ленинград|Санкт-Петербурге|{{Локатив|{{{1}}}}}}}}}]]}}}}</includeonly><noinclude> {{doc}}</noinclude> c641a956648523b96cdbeaf3fe0e9c6a4644d4ad Шаблон:Орден Ленина 10 274 709 2018-06-13T21:09:03Z ruwiki>WindEwriX 0 /* top */удаление устаревшего шаблона с помощью [[Project:AWB|AWB]] wikitext text/x-wiki {{#switch: {{{тип|}}} | воинская часть = [[Файл:Leninorder.svg|40px|link=Орден Ленина|Орден Ленина {{#if: {{{1|}}}|— {{{1}}}}}]]{{#if:{{NAMESPACE}}{{{nocat|}}}||[[Категория:Воинские части, награждённые орденом Ленина]]}} | город = [[Файл:Leninorder.svg|40px|link=Орден Ленина|Орден Ленина {{#if: {{{1|}}}|— {{{1}}}}}]]{{#if:{{NAMESPACE}}{{{nocat|}}}||[[Категория:Города, награждённые орденом Ленина]]}} | регион = [[Файл:Leninorder.svg|40px|link=Орден Ленина|Орден Ленина {{#if: {{{1|}}}|— {{{1}}}}}]]{{#if:{{NAMESPACE}}{{{nocat|}}}||[[Категория:Регионы, награждённые орденом Ленина]]}} | организация = [[Файл:Leninorder.svg|40px|link=Орден Ленина|Орден Ленина {{#if: {{{1|}}}|— {{{1}}}}}]]{{#if:{{NAMESPACE}}{{{nocat|}}}||[[Категория:Организации, награждённые орденом Ленина]]}} | СМИ | сми = [[Файл:Leninorder.svg|40px|link=Орден Ленина|Орден Ленина {{#if: {{{1|}}}|— {{{1}}}}}]]{{#if:{{NAMESPACE}}{{{nocat|}}}||[[Категория:СМИ, награждённые орденом Ленина]]}} | корабль = [[Файл:Leninorder.svg|40px|link=Орден Ленина|Орден Ленина {{#if: {{{1|}}}|— {{{1}}}}}]]{{#if:{{NAMESPACE}}{{{nocat|}}}||[[Категория:Корабли, награждённые орденом Ленина]]}} | [[Файл:SU Order of Lenin ribbon.svg|40px|link=Орден Ленина|Орден Ленина {{#if: {{{1|}}}|— {{{1}}}}}]]{{#if:{{NAMESPACE}}{{{nocat|}}}||[[Категория:Кавалеры ордена Ленина]]}} }}<noinclude> {{doc}} [[Категория:Шаблоны:Награды:СССР|Ленина]] </noinclude> 2abac17c2226c03fa1628e5e5ecd11d7a997a10a Шаблон:Скрытый 10 203 452 2018-06-14T09:27:38Z ruwiki>Iniquity 0 Iniquity переименовал страницу [[Шаблон:Скрытый]] в [[Шаблон:Скрытый блок]]: унификация названий, в схеме [[Википедия:Форум/Архив/Предложения/2018/01#Шаблоны,_скрывающие_содержимое]] wikitext text/x-wiki #перенаправление [[Шаблон:Скрытый блок]] 97cc939c1c8ece875b2ec360f85980bd6f1bbed7 Шаблон:Конец скрытого блока 10 199 444 2018-06-14T09:55:59Z ruwiki>Iniquity 0 общая документация wikitext text/x-wiki <includeonly></div></div></includeonly><noinclude> {{doc|Шаблон:Начало скрытого блока/doc}}</noinclude> 2da6ac8eb0812fb4183a70b516009d40920e281f Шаблон:Учёная степень 10 293 747 2018-06-15T22:14:30Z ruwiki>Grain of sand 0 ] потеряли wikitext text/x-wiki <includeonly>{{#switch: {{{1|}}} | кандидат = {{#switch: {{{2|}}} | архитектуры = [[кандидат архитектуры]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты архитектуры]]}} | биологических наук = [[кандидат биологических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты биологических наук]]}} | ветеринарных наук = [[кандидат ветеринарных наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты ветеринарных наук]]}} | военно-морских наук = [[кандидат военно-морских наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты военно-морских наук]]}} | военных наук = [[кандидат военных наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты военных наук]]}} | географических наук = [[кандидат географических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты географических наук]]}} | геолого-минералогических наук = [[кандидат геолого-минералогических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты геолого-минералогических наук]]}} | искусствоведения = [[кандидат искусствоведения]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты искусствоведения]]}} | исторических наук = [[кандидат исторических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты исторических наук]]}} | культурологии = [[кандидат культурологии]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты культурологии]]}} | медицинских наук = [[кандидат медицинских наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты медицинских наук]]}} | педагогических наук = [[кандидат педагогических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты педагогических наук]]}} | политических наук = [[кандидат политических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты политических наук]]}} | психологических наук = [[кандидат психологических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты психологических наук]]}} | сельскохозяйственных наук = [[кандидат сельскохозяйственных наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты сельскохозяйственных наук]]}} | социологических наук = [[кандидат социологических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты социологических наук]]}} | технических наук = [[кандидат технических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты технических наук]]}} | фармацевтических наук = [[кандидат фармацевтических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты фармацевтических наук]]}} | физико-математических наук = [[кандидат физико-математических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты физико-математических наук]]}} | филологических наук = [[кандидат филологических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты филологических наук]]}} | философских наук = [[кандидат философских наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты философских наук]]}} | химических наук = [[кандидат химических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты химических наук]]}} | экономических наук = [[кандидат экономических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты экономических наук]][[Категория:Учёные по алфавиту]][[Категория:Экономисты по алфавиту]]}} | юридических наук = [[кандидат юридических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты юридических наук]]}} | [[кандидат наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты наук]]}} }} | доктор = {{#switch: {{{2|}}} | архитектуры = [[доктор архитектуры]]{{#if:{{NAMESPACE}}||[[Категория:Доктора архитектуры]]}} | биологических наук = [[доктор биологических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора биологических наук]]}} | ветеринарных наук = [[доктор ветеринарных наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора ветеринарных наук]]}} | военно-морских наук = [[доктор военно-морских наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора военно-морских наук]]}} | военных наук = [[доктор военных наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора военных наук]]}} | географических наук = [[доктор географических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора географических наук]]}} | геолого-минералогических наук = [[доктор геолого-минералогических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора геолого-минералогических наук]]}} | искусствоведения = [[доктор искусствоведения]]{{#if:{{NAMESPACE}}||[[Категория:Доктора искусствоведения]]}} | исторических наук = [[доктор исторических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора исторических наук]]}} | культурологии = [[доктор культурологии]]{{#if:{{NAMESPACE}}||[[Категория:Доктора культурологии]]}} | медицинских наук = [[доктор медицинских наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора медицинских наук]]}} | педагогических наук = [[доктор педагогических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора педагогических наук]]}} | политических наук = [[доктор политических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора политических наук]]}} | психологических наук = [[доктор психологических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора психологических наук]]}} | сельскохозяйственных наук = [[доктор сельскохозяйственных наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора сельскохозяйственных наук]]}} | социологических наук = [[доктор социологических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора социологических наук]]}} | технических наук = [[доктор технических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора технических наук]]}} | фармацевтических наук = [[доктор фармацевтических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора фармацевтических наук]]}} | физико-математических наук = [[доктор физико-математических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора физико-математических наук]]}} | филологических наук = [[доктор филологических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора филологических наук]]}} | философских наук = [[доктор философских наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора философских наук]]}} | химических наук = [[доктор химических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора химических наук]]}} | экономических наук = [[доктор экономических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора экономических наук]][[Категория:Учёные по алфавиту]][[Категория:Экономисты по алфавиту]]}} | юридических наук = [[доктор юридических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора юридических наук]]}} | [[доктор наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора наук]]}} }} }}</includeonly><noinclude>{{doc}}</noinclude> 21fc4a364f53264639c70cc9807f6963ccb36b53 Шаблон:До символа 10 276 713 2018-07-11T11:21:59Z ruwiki>A particle for world to form 0 Для возможности использовать подстановку. wikitext text/x-wiki {{ {{{|safesubst:}}}#invoke:string2|bs|{{{1|}}}|{{{2|}}}|{{{from|1}}}}}<noinclude>{{doc}}</noinclude> 4cd51dc75d5f365cffac57c9577bd2b2f5c7cc3f Шаблон:Без начала 10 165 372 2018-07-11T22:30:39Z ruwiki>A particle for world to form 0 Для возможности использовать подстановку. wikitext text/x-wiki {{<includeonly>safesubst:</includeonly>#ifeq:{{<includeonly>safesubst:</includeonly>Str_left|{{{1}}}|{{<includeonly>safesubst:</includeonly>#expr:{{<includeonly>safesubst:</includeonly>str len|{{{2}}}*}}-1}}}}*|{{{2}}}*|{{<includeonly>safesubst:</includeonly>Str_right|{{{1}}}|{{<includeonly>safesubst:</includeonly>#expr:{{<includeonly>safesubst:</includeonly>str len|{{{2}}}*}}-1}}}}|{{{1}}}}}<noinclude>{{doc}}</noinclude> 9fbca6f1fc236cb17fe77d76891e3f9c2afa2117 Шаблон:Str rightc 10 167 376 2018-07-11T22:33:58Z ruwiki>A particle for world to form 0 Для возможности использовать подстановку. wikitext text/x-wiki {{<includeonly>safesubst:</includeonly>Str sub|{{{1}}}|{{<includeonly>safesubst:</includeonly>#expr:{{<includeonly>safesubst:</includeonly>Str len|{{{1}}}}}-{{{2}}}}}|{{{2}}}}}<noinclude>{{doc}}</noinclude> 0401d500dcc2224d44867ba0ea1f6c0fbeb758a0 Шаблон:Str left 10 146 334 2018-07-11T22:39:12Z ruwiki>A particle for world to form 0 Для возможности использовать подстановку. wikitext text/x-wiki {{<includeonly>safesubst:</includeonly>padleft:|{{{2|1}}}|{{{1|}}}}}<noinclude> {{doc}} </noinclude> c1f57b63826f4d455dcaec8d2c24a2b8268f42ec Шаблон:Str sub 10 164 370 2018-09-29T20:45:02Z ruwiki>TenBaseT 0 категории в документации wikitext text/x-wiki <includeonly>{{{{{|safesubst:}}}#invoke:String|sublength|s={{{1}}}|i={{{2|0}}}|len={{{3|0}}}}}</includeonly><noinclude> {{doc}} </noinclude> 3043790f8803e868cf6097b475fd58ba742887fe Модуль:Check for unknown parameters 828 86 146 2018-10-21T19:59:29Z ruwiki>Well-Informed Optimist 0 Защитил страницу [[Модуль:Check for unknown parameters]]: критический шаблон или модуль ([Редактирование=только администраторы] (бессрочно) [Переименование=только администраторы] (бессрочно)) Scribunto text/plain -- This module may be used to compare the arguments passed to the parent -- with a list of arguments, returning a specified result if an argument is -- not on the list local p = {} local function trim(s) return s:match('^%s*(.-)%s*$') end local function isnotempty(s) return s and trim(s) ~= '' end function p.check (frame) local args = frame.args local pargs = frame:getParent().args local ignoreblank = isnotempty(frame.args['ignoreblank']) local showblankpos = isnotempty(frame.args['showblankpositional']) local knownargs = {} local unknown = frame.args['unknown'] or 'Found _VALUE_, ' local preview = frame.args['preview'] local values = {} local res = {} local regexps = {} -- create the list of known args, regular expressions, and the return string for k, v in pairs(args) do if type(k) == 'number' then v = trim(v) knownargs[v] = 1 elseif k:find('^regexp[1-9][0-9]*$') then table.insert(regexps, '^' .. v .. '$') end end if isnotempty(preview) then preview = '<div class="hatnote" style="color:red"><strong>Предупреждение:</strong> ' .. preview .. ' (это сообщение видно только при предпросмотре страницы).</div>' elseif preview == nil then preview = unknown end -- loop over the parent args, and make sure they are on the list for k, v in pairs(pargs) do if type(k) == 'string' and knownargs[k] == nil then local knownflag = false for i, regexp in ipairs(regexps) do if mw.ustring.match(k, regexp) then knownflag = true break end end if not knownflag and ( not ignoreblank or isnotempty(v) ) then k = mw.ustring.gsub(k, '[^%w\-_ ]', '?') table.insert(values, k) end elseif type(k) == 'number' and knownargs[tostring(k)] == nil and ( showblankpos or isnotempty(v) ) then local vlen = mw.ustring.len(v) v = mw.ustring.sub(v, 1, (vlen < 25) and vlen or 25) v = mw.ustring.gsub(v, '[^%w\-_ ]', '?') table.insert(values, k .. ' = ' .. v .. ((vlen >= 25) and ' ...' or '')) end end -- add resuls to the output tables if #values > 0 then if frame:preprocess( "{{REVISIONID}}" ) == "" then unknown = preview end for k, v in pairs(values) do if v == '' then -- Fix odd bug for | = which gets stripped to the empty string and -- breaks category links v = ' ' end local r = unknown:gsub('_VALUE_', v) table.insert(res, r) end end return table.concat(res) end function p.generate (frame) local res = '{{#invoke:check for unknown parameters|check\n' .. '|unknown=' .. frame.args['unknown'] .. '\n' local checkerparams = {'ignoreblank', 'preview', 'showblankpositional'} for _, v in pairs(checkerparams) do if frame.args[v] then res = res .. '|' .. v .. '=' .. frame.args[v] .. '\n' end end local templatenamespace = frame.args[1] local templatetitle = frame.args[2] local pagepointer = mw.title.new(templatetitle, templatenamespace) -- именно такой порядок! local text = pagepointer.getContent(pagepointer) local params = {} for param in string.gmatch(text, '\{\{\{([^\|\}]*)') do params[#params+1] = mw.text.trim(param) end table.sort(params) for k, v in pairs(params) do if k == 1 or v ~= params[k-1] then res = res .. '|' .. v end end res = res .. '}}' return res end return p 718ece7132a40acc051a3da4cdf668a76c02d10d Шаблон:Lang-en2 10 283 727 2018-12-28T14:01:00Z ruwiki>Dima st bk 0 Dima st bk переименовал страницу [[Шаблон:Langi-en2]] в [[Шаблон:Lang-en2]]: под стандарт wikitext text/x-wiki {{langi|en|{{{1}}}}}<noinclude> {{doc|Lang/doc}} </noinclude> 0471cf4d45a13ece481915d5c3e55db65d6aca04 Шаблон:No-doc 10 187 418 2019-01-17T08:39:04Z ruwiki>Dima st bk 0 Защитил страницу [[Шаблон:No-doc]]: критический шаблон или модуль ([Редактирование=только автоподтверждённые] (бессрочно) [Переименование=только администраторы] (бессрочно)) wikitext text/x-wiki {{#ifeq: {{SUBPAGENAME}} | doc || {{#if: {{#if: {{yesno|{{{nocat|}}}}} | x }}{{#switch: {{NAMESPACE}} | {{ns:10}} | {{ns:828}} = | x }} || {{{1|}}} }} }}<noinclude>{{doc}}</noinclude> da013ca5b5f97f94bee392ff3a4488046f2ceac7 Шаблон:МестоРождения 10 270 701 2019-03-11T14:32:34Z ruwiki>DonRumata 0 + параметр nocat по запросу [[ВП:Ф-Т#Вопрос про nocat]] wikitext text/x-wiki <includeonly>{{#if:{{{3|}}}|[[{{{3}}}|{{{1}}}]]|{{#if:{{{1|}}}|[[{{{1}}}]]}}}}{{#if:{{NAMESPACE}}{{{nocat|}}}||{{#if:{{{1|}}}|[[Категория:Персоналии по алфавиту]][[Категория:Родившиеся {{#if:{{{2|}}}|{{{2}}}|в {{#ifeq:{{{1}}}|Ленинград|Санкт-Петербурге|{{Локатив|{{{1}}}}}}}}}]]}}}}</includeonly><noinclude> {{doc}}</noinclude> e03e5faeefe2ece8cfa949e62031800a70ec9773 Шаблон:Big 10 73 118 2019-04-25T13:33:41Z ruwiki>QBA-bot 0 Защитил страницу [[Шаблон:Big]]: критический шаблон или модуль (каскадная защита) ([Редактирование=только автоподтверждённые] (бессрочно) [Переименование=только автоподтверждённые] (бессрочно)) wikitext text/x-wiki <span style="font-size:120%;">{{{1}}}</span><noinclude> {{documentation}} <!-- PLEASE ADD CATEGORIES TO THE /doc SUBPAGE, THANKS --> </noinclude> 233a0192f59d7a0c6fef6b818e8d1c96d48295d2 Шаблон:Заготовка шаблона 10 298 757 2019-04-25T13:33:44Z ruwiki>QBA-bot 0 Защитил страницу [[Шаблон:Заготовка шаблона]]: критический шаблон или модуль (каскадная защита) ([Редактирование=только автоподтверждённые] (бессрочно) [Переименование=только автоподтверждённые] (бессрочно)) wikitext text/x-wiki {{#invoke:TemplateDataDoc|generateBlank|{{#if:{{{1|}}}|{{{1}}}|{{BASEPAGENAME}}}}|description={{{описание|}}}}}<noinclude>{{doc}}</noinclude> b451404244fd6898bc134564ddcb8941eca7f64a Шаблон:Module other 10 95 161 2019-04-25T13:37:07Z ruwiki>QBA-bot 0 Защитил страницу [[Шаблон:Module other]]: критический шаблон или модуль (каскадная защита) ([Редактирование=только автоподтверждённые] (бессрочно) [Переименование=только автоподтверждённые] (бессрочно)) wikitext text/x-wiki {{#switch: <!--If no or empty "demospace" parameter then detect namespace--> {{#if:{{{demospace|}}} | {{lc: {{{demospace}}} }} <!--Use lower case "demospace"--> | {{#ifeq:{{NAMESPACE}}|{{ns:Module}} | module | other }} }} | module = {{{1|}}} | other | #default = {{{2|}}} }}<!--End switch--><noinclude> {{doc}} <!-- Add categories and interwikis to the /doc subpage, not here! --> </noinclude> 097d5ea3648fcbbe0ccd87e8f217c713e97922c7 Шаблон:Cross 10 205 458 2019-04-25T13:39:39Z ruwiki>QBA-bot 0 Защитил страницу [[Шаблон:Cross]]: критический шаблон или модуль (каскадная защита) ([Редактирование=только автоподтверждённые] (бессрочно) [Переименование=только автоподтверждённые] (бессрочно)) wikitext text/x-wiki [[File:X mark.svg|{{{1|20}}}px|link=|alt=]]<span style="display:none">N</span><!--template:cross--><noinclude> {{documentation}} </noinclude> ed4b409e99cfe41368cc2f86462c7f46372ac8bb Шаблон:Tick 10 204 456 2019-04-25T13:40:45Z ruwiki>QBA-bot 0 Защитил страницу [[Шаблон:Tick]]: критический шаблон или модуль (каскадная защита) ([Редактирование=только автоподтверждённые] (бессрочно) [Переименование=только автоподтверждённые] (бессрочно)) wikitext text/x-wiki #перенаправление [[Шаблон:Ok]] f0887beb67bfbdc74fa97e8dd35f78474edfcefc Шаблон:Demo 10 118 277 2019-04-25T13:40:59Z ruwiki>QBA-bot 0 Защитил страницу [[Шаблон:Demo]]: критический шаблон или модуль (каскадная защита) ([Редактирование=только автоподтверждённые] (бессрочно) [Переименование=только автоподтверждённые] (бессрочно)) wikitext text/x-wiki {{#invoke:Demo|main}}<noinclude>{{documentation}}</noinclude> e458e378477c6077a01987f334fdc73bee48512c Модуль:Wikidata/count 828 163 368 2019-06-29T03:57:18Z ruwiki>Dima st bk 0 Изменил уровень защиты [[Модуль:Wikidata/count]]: критический шаблон или модуль ([Редактирование=только администраторы] (бессрочно) [Переименование=только администраторы] (бессрочно)) Scribunto text/plain local p = {} function p.getCount( context, options ) if ( not context ) then error( 'context not specified' ); end; if ( not options ) then error( 'options not specified' ); end; if ( not options.entity ) then error( 'options.entity missing' ); end; local claims; if options.property then -- TODO: Почему тут может не быть property? claims = context.selectClaims( options, options.property ); end if claims == nil then return ''; --TODO error? end return table.getn(claims); end function p.isMultiple( context, options ) local count = p.getCount( context, options ); local multiple = ''; if( count ~= nil and count ~= '' and count > 1 ) then multiple = 1; end return multiple; end return p 8ccf5dd7170a466674627b0afdf32c6bd2318154 Шаблон:Uses Wikidata 10 301 763 2019-08-10T23:17:15Z ruwiki>Serhio Magpie 0 оформление кода при помощи [[u:JWBTH/ATP|скрипта]] wikitext text/x-wiki {{Родственный проект | проект = викиданные | текст = Этот {{module other|модуль|шаблон}} использует {{#if: {{{раздел|{{{section|}}}}}} | Свойства [[Викиданные|Викиданных]]; детальней см. [[#{{{раздел|{{{section|}}}}}}|§&nbsp;{{{раздел|{{{section}}}}}}]]. | [[ВП:Викиданные{{!}}свойств{{#if:{{{2|}}}|а|о}} Викиданных]]: }} | внизу = {{#if: {{{раздел|{{{section|}}}}}} || <div class="plainlist"><ul>{{#invoke:Uses Wikidata|usesProperty}}</ul></div> }} }}<noinclude> {{doc}} </noinclude> 5d62bf72bc1eea3b38bb5a9cd82eecf54b02fe45 Модуль:TableTools 828 125 292 2019-08-26T06:20:31Z ruwiki>Serhio Magpie 0 Обновлено с https://en.wikipedia.org/w/index.php?title=Module:TableTools&oldid=887403551 Scribunto text/plain --[[ ------------------------------------------------------------------------------------ -- TableTools -- -- -- -- This module includes a number of functions for dealing with Lua tables. -- -- It is a meta-module, meant to be called from other Lua modules, and should -- -- not be called directly from #invoke. -- ------------------------------------------------------------------------------------ --]] local libraryUtil = require('libraryUtil') local p = {} -- Define often-used variables and functions. local floor = math.floor local infinity = math.huge local checkType = libraryUtil.checkType local checkTypeMulti = libraryUtil.checkTypeMulti --[[ ------------------------------------------------------------------------------------ -- isPositiveInteger -- -- This function returns true if the given value is a positive integer, and false -- if not. Although it doesn't operate on tables, it is included here as it is -- useful for determining whether a given table key is in the array part or the -- hash part of a table. ------------------------------------------------------------------------------------ --]] function p.isPositiveInteger(v) if type(v) == 'number' and v >= 1 and floor(v) == v and v < infinity then return true else return false end end --[[ ------------------------------------------------------------------------------------ -- isNan -- -- This function returns true if the given number is a NaN value, and false -- if not. Although it doesn't operate on tables, it is included here as it is -- useful for determining whether a value can be a valid table key. Lua will -- generate an error if a NaN is used as a table key. ------------------------------------------------------------------------------------ --]] function p.isNan(v) if type(v) == 'number' and tostring(v) == '-nan' then return true else return false end end --[[ ------------------------------------------------------------------------------------ -- shallowClone -- -- This returns a clone of a table. The value returned is a new table, but all -- subtables and functions are shared. Metamethods are respected, but the returned -- table will have no metatable of its own. ------------------------------------------------------------------------------------ --]] function p.shallowClone(t) local ret = {} for k, v in pairs(t) do ret[k] = v end return ret end --[[ ------------------------------------------------------------------------------------ -- removeDuplicates -- -- This removes duplicate values from an array. Non-positive-integer keys are -- ignored. The earliest value is kept, and all subsequent duplicate values are -- removed, but otherwise the array order is unchanged. ------------------------------------------------------------------------------------ --]] function p.removeDuplicates(t) checkType('removeDuplicates', 1, t, 'table') local isNan = p.isNan local ret, exists = {}, {} for i, v in ipairs(t) do if isNan(v) then -- NaNs can't be table keys, and they are also unique, so we don't need to check existence. ret[#ret + 1] = v else if not exists[v] then ret[#ret + 1] = v exists[v] = true end end end return ret end --[[ ------------------------------------------------------------------------------------ -- numKeys -- -- This takes a table and returns an array containing the numbers of any numerical -- keys that have non-nil values, sorted in numerical order. ------------------------------------------------------------------------------------ --]] function p.numKeys(t) checkType('numKeys', 1, t, 'table') local isPositiveInteger = p.isPositiveInteger local nums = {} for k, v in pairs(t) do if isPositiveInteger(k) then nums[#nums + 1] = k end end table.sort(nums) return nums end --[[ ------------------------------------------------------------------------------------ -- affixNums -- -- This takes a table and returns an array containing the numbers of keys with the -- specified prefix and suffix. For example, for the table -- {a1 = 'foo', a3 = 'bar', a6 = 'baz'} and the prefix "a", affixNums will -- return {1, 3, 6}. ------------------------------------------------------------------------------------ --]] function p.affixNums(t, prefix, suffix) checkType('affixNums', 1, t, 'table') checkType('affixNums', 2, prefix, 'string', true) checkType('affixNums', 3, suffix, 'string', true) local function cleanPattern(s) -- Cleans a pattern so that the magic characters ()%.[]*+-?^$ are interpreted literally. s = s:gsub('([%(%)%%%.%[%]%*%+%-%?%^%$])', '%%%1') return s end prefix = prefix or '' suffix = suffix or '' prefix = cleanPattern(prefix) suffix = cleanPattern(suffix) local pattern = '^' .. prefix .. '([1-9]%d*)' .. suffix .. '$' local nums = {} for k, v in pairs(t) do if type(k) == 'string' then local num = mw.ustring.match(k, pattern) if num then nums[#nums + 1] = tonumber(num) end end end table.sort(nums) return nums end --[[ ------------------------------------------------------------------------------------ -- numData -- -- Given a table with keys like ("foo1", "bar1", "foo2", "baz2"), returns a table -- of subtables in the format -- { [1] = {foo = 'text', bar = 'text'}, [2] = {foo = 'text', baz = 'text'} } -- Keys that don't end with an integer are stored in a subtable named "other". -- The compress option compresses the table so that it can be iterated over with -- ipairs. ------------------------------------------------------------------------------------ --]] function p.numData(t, compress) checkType('numData', 1, t, 'table') checkType('numData', 2, compress, 'boolean', true) local ret = {} for k, v in pairs(t) do local prefix, num = mw.ustring.match(tostring(k), '^([^0-9]*)([1-9][0-9]*)$') if num then num = tonumber(num) local subtable = ret[num] or {} if prefix == '' then -- Positional parameters match the blank string; put them at the start of the subtable instead. prefix = 1 end subtable[prefix] = v ret[num] = subtable else local subtable = ret.other or {} subtable[k] = v ret.other = subtable end end if compress then local other = ret.other ret = p.compressSparseArray(ret) ret.other = other end return ret end --[[ ------------------------------------------------------------------------------------ -- compressSparseArray -- -- This takes an array with one or more nil values, and removes the nil values -- while preserving the order, so that the array can be safely traversed with -- ipairs. ------------------------------------------------------------------------------------ --]] function p.compressSparseArray(t) checkType('compressSparseArray', 1, t, 'table') local ret = {} local nums = p.numKeys(t) for _, num in ipairs(nums) do ret[#ret + 1] = t[num] end return ret end --[[ ------------------------------------------------------------------------------------ -- sparseIpairs -- -- This is an iterator for sparse arrays. It can be used like ipairs, but can -- handle nil values. ------------------------------------------------------------------------------------ --]] function p.sparseIpairs(t) checkType('sparseIpairs', 1, t, 'table') local nums = p.numKeys(t) local i = 0 local lim = #nums return function () i = i + 1 if i <= lim then local key = nums[i] return key, t[key] else return nil, nil end end end --[[ ------------------------------------------------------------------------------------ -- size -- -- This returns the size of a key/value pair table. It will also work on arrays, -- but for arrays it is more efficient to use the # operator. ------------------------------------------------------------------------------------ --]] function p.size(t) checkType('size', 1, t, 'table') local i = 0 for k in pairs(t) do i = i + 1 end return i end local function defaultKeySort(item1, item2) -- "number" < "string", so numbers will be sorted before strings. local type1, type2 = type(item1), type(item2) if type1 ~= type2 then return type1 < type2 else -- This will fail with table, boolean, function. return item1 < item2 end end --[[ Returns a list of the keys in a table, sorted using either a default comparison function or a custom keySort function. ]] function p.keysToList(t, keySort, checked) if not checked then checkType('keysToList', 1, t, 'table') checkTypeMulti('keysToList', 2, keySort, { 'function', 'boolean', 'nil' }) end local list = {} local index = 1 for key, value in pairs(t) do list[index] = key index = index + 1 end if keySort ~= false then keySort = type(keySort) == 'function' and keySort or defaultKeySort table.sort(list, keySort) end return list end --[[ Iterates through a table, with the keys sorted using the keysToList function. If there are only numerical keys, sparseIpairs is probably more efficient. ]] function p.sortedPairs(t, keySort) checkType('sortedPairs', 1, t, 'table') checkType('sortedPairs', 2, keySort, 'function', true) local list = p.keysToList(t, keySort, true) local i = 0 return function() i = i + 1 local key = list[i] if key ~= nil then return key, t[key] else return nil, nil end end end --[[ Returns true if all keys in the table are consecutive integers starting at 1. --]] function p.isArray(t) checkType("isArray", 1, t, "table") local i = 0 for k, v in pairs(t) do i = i + 1 if t[i] == nil then return false end end return true end -- { "a", "b", "c" } -> { a = 1, b = 2, c = 3 } function p.invert(array) checkType("invert", 1, array, "table") local map = {} for i, v in ipairs(array) do map[v] = i end return map end --[[ { "a", "b", "c" } -> { ["a"] = true, ["b"] = true, ["c"] = true } --]] function p.listToSet(t) checkType("listToSet", 1, t, "table") local set = {} for _, item in ipairs(t) do set[item] = true end return set end --[[ Recursive deep copy function. Preserves identities of subtables. ]] local function _deepCopy(orig, includeMetatable, already_seen) -- Stores copies of tables indexed by the original table. already_seen = already_seen or {} local copy = already_seen[orig] if copy ~= nil then return copy end if type(orig) == 'table' then copy = {} for orig_key, orig_value in pairs(orig) do copy[deepcopy(orig_key, includeMetatable, already_seen)] = deepcopy(orig_value, includeMetatable, already_seen) end already_seen[orig] = copy if includeMetatable then local mt = getmetatable(orig) if mt ~= nil then local mt_copy = deepcopy(mt, includeMetatable, already_seen) setmetatable(copy, mt_copy) already_seen[mt] = mt_copy end end else -- number, string, boolean, etc copy = orig end return copy end function p.deepCopy(orig, noMetatable, already_seen) checkType("deepCopy", 3, already_seen, "table", true) return _deepCopy(orig, not noMetatable, already_seen) end --[[ Concatenates all values in the table that are indexed by a number, in order. sparseConcat{ a, nil, c, d } => "acd" sparseConcat{ nil, b, c, d } => "bcd" ]] function p.sparseConcat(t, sep, i, j) local list = {} local list_i = 0 for _, v in p.sparseIpairs(t) do list_i = list_i + 1 list[list_i] = v end return table.concat(list, sep, i, j) end --[[ -- This returns the length of a table, or the first integer key n counting from -- 1 such that t[n + 1] is nil. It is similar to the operator #, but may return -- a different value when there are gaps in the array portion of the table. -- Intended to be used on data loaded with mw.loadData. For other tables, use #. -- Note: #frame.args in frame object always be set to 0, regardless of -- the number of unnamed template parameters, so use this function for -- frame.args. --]] function p.length(t) local i = 1 while t[i] ~= nil do i = i + 1 end return i - 1 end function p.inArray(arr, valueToFind) checkType("inArray", 1, arr, "table") -- if valueToFind is nil, error? for _, v in ipairs(arr) do if v == valueToFind then return true end end return false end return p fe918509f168332267834b3a6f5c219a9de5b2e7 Шаблон:Br separated entries 10 155 352 2019-08-30T23:08:35Z ruwiki>Ле Лой 0 Защитил страницу [[Шаблон:Br separated entries]]: критический шаблон или модуль ([Редактирование=только администраторы] (бессрочно) [Переименование=только администраторы] (бессрочно)) wikitext text/x-wiki {{<includeonly>safesubst:</includeonly>#invoke:Separated entries|br}}<noinclude> {{doc}} </noinclude> 2113c3c6e95a84235b9f7a85e7ea17208e8f91df Шаблон:Tp 10 216 480 2019-10-20T16:34:25Z ruwiki>Helgo13 0 Helgo13 переименовал страницу [[Шаблон:Tp]] в [[Шаблон:Tlp]]: [[Википедия:К объединению/10 октября 2019#Шаблон:T → Шаблон:Tl, Шаблон:Tp → Шаблон:Tlp]] wikitext text/x-wiki #перенаправление [[Шаблон:Tlp]] d882ad71d959bf88034ac86b892a2686c44e6a87 Шаблон:T 10 161 364 2019-10-20T16:35:32Z ruwiki>Helgo13 0 Helgo13 переименовал страницу [[Шаблон:T]] в [[Шаблон:Tl]] wikitext text/x-wiki #перенаправление [[Шаблон:Tl]] c0a76efe437d8a513d9f6878297f399a23944abd 545 364 2021-07-29T21:07:36Z ruwiki>WerySkok 0 1 версия импортирована: Импорт Инфобокса из Русскоязычной википедии. wikitext text/x-wiki #перенаправление [[Шаблон:Tl]] c0a76efe437d8a513d9f6878297f399a23944abd Шаблон:Tl 10 162 366 2019-10-20T16:35:32Z ruwiki>Helgo13 0 Helgo13 переименовал страницу [[Шаблон:T]] в [[Шаблон:Tl]] wikitext text/x-wiki {{{{{|safesubst:}}}#invoke: Template call code | withoutParams }}<noinclude>{{doc}}</noinclude> 61fe4d068895a5e7e5802767f5d7df71a7561c57 Шаблон:Карточка/внизу 10 137 316 2019-11-13T23:18:52Z ruwiki>Serhio Magpie 0 Перенесено в общие стили wikitext text/x-wiki <includeonly>{{#if:{{{внизу|}}}|<tr><td colspan="2" class="infobox-below {{{класс_внизу|}}}" style="{{{стиль_внизу_общий|}}};{{{стиль_внизу|}}}">{{{внизу|}}}</td></tr>}}</includeonly><noinclude> {{doc}} </noinclude> 169fb2d10b0847c2fd677eda9f159ba99025198f Шаблон:If-wikidata 10 148 338 2019-11-13T23:40:02Z ruwiki>Serhio Magpie 0 + from wikitext text/x-wiki {{#switch:{{wikidata|{{{1|}}}|{{{2|}}}|plain={{{plain|true}}}|from={{{from|}}}|somevalue={{{somevalue|}}}|novalue={{{novalue|}}}}}|значение отсутствует|={{{4|}}}|#default={{{3}}}}}<noinclude> {{doc}} </noinclude> a8a37fd2c4f1a266ec48783d7d0ad22cdcd812cb Модуль:Карточка 828 83 140 2020-01-09T11:04:31Z ruwiki>SADIQUI 0 Scribunto text/plain -- -- Модуль для реализации шаблона {{Карточка}} -- local p = {} local HtmlBuilder = require('Module:HtmlBuilder') local args = {} local origArgs local argsAliases = {} local root local function union(t1, t2) -- Возвращает объединение значений двух таблиц в виде последовательности. local vals = {} for k, v in pairs(t1) do vals[v] = true end for k, v in pairs(t2) do vals[v] = true end local ret = {} for k, v in pairs(vals) do table.insert(ret, k) end return ret end local function getArgNums(prefix) -- Возвращает таблицу индексов существующих полей с заданным префиксом, -- например, для префикса 'текст' и установленных 'текст1', 'текст2' и -- 'текст5' возвращает {1, 2, 5}. local nums = {} for k, v in pairs(args) do local num = tostring(k):match('^' .. prefix .. '([1-9]%d*)$') if num then table.insert(nums, tonumber(num)) end end table.sort(nums) return nums end local function addRow(rowArgs) -- Добавляет строку в карточку (заголовок или метку/текст). if rowArgs.header then root .tag('tr') .addClass(rowArgs.rowclass) .attr('id', rowArgs.rowid) .tag('th') .attr('colspan', 2) .attr('id', rowArgs.headerid) .addClass(rowArgs.class) .addClass(args['класс_заголовков']) .css('text-align', 'center') .cssText(args['стиль_заголовков']) .wikitext(rowArgs.header) elseif rowArgs.data then local row = root.tag('tr') row.addClass(rowArgs.rowclass) row.attr('id', rowArgs.rowid) if rowArgs.label then row .tag('th') .attr('scope', 'row') .attr('id', rowArgs.labelid) .cssText(args['стиль_меток']) .wikitext(rowArgs.label) .done() end local dataCell = row.tag('td') if not rowArgs.label then dataCell .attr('colspan', 2) .css('text-align', 'center') end dataCell .attr('id', rowArgs.dataid) .addClass(rowArgs.class) .cssText(rowArgs.datastyle) .newline() .wikitext(rowArgs.data) end end local function renderTitle() if not args['название'] then return end root .tag('caption') .addClass(args['класс_названия']) .cssText(args['стиль_названия']) .wikitext(args['название']) end local function renderAboveRow() if not args['вверху'] then return end root .tag('tr') .tag('th') .attr('colspan', 2) .addClass(args['класс_вверху']) .css('text-align', 'center') .css('font-size', '125%') .css('font-weight', 'bold') .cssText(args['стиль_вверху']) .wikitext(args['вверху']) end local function renderAbove2Row() if not args['вверху2'] then return end root .tag('tr') .tag('th') .attr('colspan', 2) .addClass(args['класс_вверху2']) .css('text-align', 'center') .css('font-style', 'oblique') .cssText(args['стиль_вверху2']) .wikitext(args['вверху2']) end local function renderBelowRow() if not args['внизу'] then return end root .tag('tr') .tag('td') .attr('colspan', 2) .addClass(args['класс_внизу']) .css('text-align', 'center') .cssText(args['стиль_внизу']) .newline() .wikitext(args['внизу']) end local function renderSubheaders() if args['подзаголовок'] then args['подзаголовок1'] = args['подзаголовок'] end if args['класс_ряда_подзаголовка'] then args['класс_ряда_подзаголовка1'] = args['класс_ряда_подзаголовка'] end local subheadernums = getArgNums('подзаголовок') for k, num in ipairs(subheadernums) do addRow({ data = args['подзаголовок' .. tostring(num)], datastyle = args['стиль_подзаголовков'] or args['стиль_подзаголовка' .. tostring(num)], class = args['класс_подзаголовков'], rowclass = args['класс_ряда_подзаголовка' .. tostring(num)] }) end end local function renderImages() if args['изображение'] then args['изображение1'] = args['изображение'] end if args['подпись'] then args['подпись1'] = args['подпись'] end local imagenums = getArgNums('изображение') for k, num in ipairs(imagenums) do local caption = args['подпись' .. tostring(num)] local data = HtmlBuilder.create().wikitext(args['изображение' .. tostring(num)]) if caption then data .tag('div') .cssText(args['стиль_подписи']) .wikitext(caption) end addRow({ data = tostring(data), datastyle = args['стиль_изображения'], class = args['класс_изображения'], rowclass = args['класс_ряда_изображения' .. tostring(num)] }) end end local function renderRows() -- Объединяет индексы заголовков и текстовых строк карточки -- и визуализирует их в правильном порядке через addRow. local rownums = union(getArgNums('заголовок'), getArgNums('текст')) table.sort(rownums) for k, num in ipairs(rownums) do addRow({ header = args['заголовок' .. tostring(num)], label = args['метка' .. tostring(num)], data = args['текст' .. tostring(num)], datastyle = args['стиль_текста'], class = args['класс' .. tostring(num)], rowclass = args['класс_ряда' .. tostring(num)], dataid = args['id_текста' .. tostring(num)], labelid = args['id_метки' .. tostring(num)], headerid = args['id_заголовка' .. tostring(num)], rowid = args['id_ряда' .. tostring(num)] }) end end local function renderNavBar() if not args['имя'] then return end root .tag('tr') .tag('td') .attr('colspan', 2) .css('text-align', 'right') .wikitext(mw.getCurrentFrame():expandTemplate({ title = 'Tnavbar', args = { args['имя'] } })) end local function isSet(x) -- Возвращает истину, если x задан и не пустой -- Внимание: отличается от enwiki! В enwiki проверяется на равенство 'yes' return x and x ~= '' end local function renderItalicTitle() -- Внимание: отличается от enwiki. В enwiki ожидается yes или force, здесь работает любое значение if isSet(args['заголовок_курсивом']) then root.wikitext(mw.getCurrentFrame():expandTemplate({title = 'Заголовок курсивом'})) end end local function renderTrackingCategories() if not isSet(args.nocat) then if #(getArgNums('текст')) == 0 and mw.title.getCurrentTitle().namespace == 0 then root.wikitext('[[Категория:Статьи с карточкой без заполненных данных]]') end if isSet(args['внедрение']) and args['название'] then root.wikitext('[[Категория:Статьи со встроенной карточкой и параметром названия]]') end end end local function _infobox() -- Задание общей страктуры карточки с добавлением стилей -- для карточек-потомков. if not isSet(args['внедрение']) then root = HtmlBuilder.create('table') root .addClass('infobox') .addClass(args['класс_тела']) if isSet(args['подкарточка']) then root .css('padding', '0') .css('border', 'none') .css('margin', '-2px') .css('width', 'auto') .css('min-width', '100%') .css('font-size', '100%') .css('clear', 'none') .css('float', 'none') .css('background-color', 'transparent') end -- Микроразметка if isSet(args['микр_тела']) then root .attr('itemscope', 'itemscope') .attr('itemtype', args['микр_тела']) end root .cssText(args['стиль_тела']) renderTitle() renderAboveRow() renderAbove2Row() else root = HtmlBuilder.create() root .wikitext(args['название']) end renderSubheaders() renderImages() renderRows() renderBelowRow() renderNavBar() renderItalicTitle() renderTrackingCategories() return tostring(root) end local function preprocessSingleArg(argName) -- Добавляет аргумент в таблицу аргументов, если он определён и не пустой. -- Пустые аргументы не обрабатываются, как и в ParserFunctions. if origArgs[argName] and origArgs[argName] ~= '' then args[argName] = origArgs[argName] end end local function translateArg(aliasArgName,localArgName) -- Функция добавляет поддержку алиасов параметров (например, на другом языке) -- Добавляем алиас параметра в таблицу алиасов -- Для одного параметра может быть несколько алиасов -- Нумерованные параметры(текст1 и т.д.) заносятся без номера if not argsAliases[localArgName] then argsAliases[localArgName] = {} end table.insert(argsAliases[localArgName], aliasArgName) -- Пока для тестирования: значения алиасов добавляются в таблицу аргументов -- Нумерованные параметры работать не будут if origArgs[localArgName] and origArgs[localArgName] ~= '' then -- параметр уже задан на локальном языке else -- если алиас задан и не пустой if origArgs[aliasArgName] and origArgs[aliasArgName] ~= '' then origArgs[localArgName] = origArgs[aliasArgName] end end end local function preprocessArgs(prefixTable, step) -- Сохраняет параметры с заданными префиксами в таблицу args, последовательно обходя -- аргументы в нужном порядке и с нужным шагом. Благодаря этому сноски и пр. появляются -- в правильном порядке. prefixTable — массив таблиц, каждая из которых может содержать -- два поля: поле-строку префикса (обязательно) и поле-таблицу зависимых параметров. -- Эта функция всегда обрабатывает параметры с префиксом, но зависимые параметры -- обрабатываются, только если параметр с префиксом задан и не пустой. if type(prefixTable) ~= 'table' then error("В качестве таблицы префиксов должна использоваться таблица", 2) end if type(step) ~= 'number' then error("Недопустимый тип параметра шага", 2) end -- Проверка правильности данных и обработка параметров без суффиксов. for i,v in ipairs(prefixTable) do if type(v) ~= 'table' or type(v.prefix) ~= "string" or (v.depend and type(v.depend) ~= 'table') then error('Недопустимая таблица префиксов preprocessArgs', 2) end preprocessSingleArg(v.prefix) -- Зависимые параметры обрабатываются, только если параметр с префиксом задан и не пустой. if args[v.prefix] and v.depend then for j, dependValue in ipairs(v.depend) do if type(dependValue) ~= 'string' then error('Недопустимый тип зависимого параметра в таблице preprocessArgs') end preprocessSingleArg(dependValue) end end end -- Обход нумерованных аргументов. local a = 1 -- Переменная-счётчик. local moreArgumentsExist = true while moreArgumentsExist == true do moreArgumentsExist = false for i = a, a + step - 1 do for j,v in ipairs(prefixTable) do local prefixArgName = v.prefix .. tostring(i) if origArgs[prefixArgName] then moreArgumentsExist = true -- Искать аргументы дальше, если был хотя бы один (в т. ч. пустой) preprocessSingleArg(prefixArgName) end -- Обрабатываем зависимые аргументы, если определена таблица зависимостей, -- а также задан не пустой аргумент с префиксом, либо обрабатывается -- "префикс1" и "префикс" задан (например, "изображение1" является синонимом для "изображение"). if v.depend and (args[prefixArgName] or (i == 1 and args[v.prefix])) then for j,dependValue in ipairs(v.depend) do local dependArgName = dependValue .. tostring(i) preprocessSingleArg(dependArgName) end end end end a = a + step end end function p.infobox(frame) -- При запуске через #invoke аргументы передаются через стандартную систему. -- При тестировании также можно передавать таблицу аргументов через frame. if frame == mw.getCurrentFrame() then origArgs = frame:getParent().args else origArgs = frame end -- Поддержка параметров из англовики translateArg('child','внедрение') translateArg('bodyclass','класс_тела') translateArg('subbox','подкарточка') translateArg('bodystyle','стиль_тела') translateArg('title','название') translateArg('titleclass','класс_названия') translateArg('titlestyle','стиль_названия') translateArg('above','вверху') translateArg('aboveclass','класс_вверху') translateArg('abovestyle','стиль_вверху') translateArg('subheader','подзаголовок') translateArg('subheaderrowstyle','стиль_подзаголовка') translateArg('subheaderrowclass','класс_подзаголовка') translateArg('subheaderstyle','стиль_подзаголовков') translateArg('subheaderclass','класс_подзаголовков') translateArg('image','изображение') translateArg('caption','подпись') translateArg('imagerowclass','класс_ряда_изображения') translateArg('captionstyle','стиль_подписи') translateArg('imagestyle','стиль_изображения') translateArg('imageclass','класс_изображения') translateArg('header','заголовок') translateArg('data','текст') translateArg('label','метка') translateArg('rowclass','класс_ряда') translateArg('class','класс') translateArg('dataid','id_текста') translateArg('labelid','id_метки') translateArg('headerid','id_заголовка') translateArg('rowid','id_ряда') translateArg('headerclass','класс_заголовков') translateArg('headerstyle','стиль_заголовков') translateArg('labelstyle','стиль_меток') translateArg('datastyle','стиль_текста') translateArg('below','внизу') translateArg('belowclass','класс_внизу') translateArg('belowstyle','стиль_внизу') translateArg('name','имя') --translateArg('italic title','заголовок_курсивом') --translateArg('','') -- Параметры обрабатываются по направлению чтения карточки, чтобы -- сноски и др. отображались в нужных местах. Параметры, зависящие -- от других параметров, обрабатываются только при наличии других параметров, -- чтобы в списке сносок не возникали нежелательные сноски. preprocessSingleArg('внедрение') preprocessSingleArg('класс_тела') preprocessSingleArg('подкарточка') preprocessSingleArg('стиль_тела') preprocessSingleArg('название') preprocessSingleArg('класс_названия') preprocessSingleArg('стиль_названия') preprocessSingleArg('вверху') preprocessSingleArg('класс_вверху') preprocessSingleArg('стиль_вверху') preprocessSingleArg('вверху2') preprocessSingleArg('класс_вверху2') preprocessSingleArg('стиль_вверху2') preprocessArgs({ {prefix = 'подзаголовок', depend = {'стиль_подзаголовка', 'класс_подзаголовка'}} }, 10) preprocessSingleArg('стиль_подзаголовков') preprocessSingleArg('класс_подзаголовков') preprocessArgs({ {prefix = 'изображение', depend = {'подпись', 'класс_ряда_изображения'}} }, 10) preprocessSingleArg('стиль_подписи') preprocessSingleArg('стиль_изображения') preprocessSingleArg('класс_изображения') preprocessArgs({ {prefix = 'заголовок'}, {prefix = 'текст', depend = {'метка'}}, {prefix = 'класс_ряда'}, {prefix = 'класс'}, {prefix = 'id_текста'}, {prefix = 'id_метки'}, {prefix = 'id_заголовка'}, {prefix = 'id_ряда'} }, 50) preprocessSingleArg('класс_заголовков') preprocessSingleArg('стиль_заголовков') preprocessSingleArg('стиль_меток') preprocessSingleArg('стиль_текста') preprocessSingleArg('внизу') preprocessSingleArg('класс_внизу') preprocessSingleArg('стиль_внизу') preprocessSingleArg('имя') preprocessSingleArg('заголовок_курсивом') preprocessSingleArg('nocat') return _infobox() end return p 2c8d650c985ea4b045be261f1a7a32917dfba56f Модуль:String2 828 279 719 2020-02-07T22:56:05Z ruwiki>Serhio Magpie 0 + ucfirst Scribunto text/plain --[[ Кое-какие дополнительные функции для строк ]] local M = { bs=function(f)-- первый параметр до начала второго параметра (или до конца, если он не встретился) --необяз. 3-й параметр - с какого по номеру (с 1) символа начинать поиск. return mw.ustring.sub(f.args[1], 1, (mw.ustring.find(f.args[1],f.args[2],tonumber(f.args[3] or 1),true) or 0)-1) end; as=function(f)-- первый параметр после начала второго параметра return mw.ustring.sub(f.args[1], (mw.ustring.find(f.args[1],f.args[2],1,true) or 0)+1) end; Tr=function(s,f,t,cf,df,sf)-- транслитерация первого параметра путём замены символов из второго параметра символами из третьего. -- Отдельными параметрами можно передавать флаги c, d и s, как в Perl; диапазоны в замене не работают, только в левой части -- (т.е. дефис надо передавать первым или последним). Второй результат - число заменённых символов local r, l, l2 = {}, mw.ustring.len(f), mw.ustring.len(t); for i = 1, l do r[mw.ustring.sub(f,i,i)] = i<=l2 and mw.ustring.sub(t,i,i) or df and '' or mw.ustring.sub(t,l2,l2) end local n2=0; local res, n = mw.ustring.gsub( s, ('[%s%s]%s'):format( cf and '^' or '', f:gsub('%','%%'):gsub(']','%]'):gsub('^%^','%^'), sf and '+' or '' ), sf and function(cc) n2 = n2+mw.ustring.len(cc)-1; return mw.ustring.gsub(cc,'.',r) end or r ) return res, n+n2 end; -- tr = function(f) return (M.Tr(f.args[1],f.args[2],f.args[3],f.args['c'],f.args['d'],f.args['s'])) end;-- транслитерировать -- trс = function(f) return ({M.Tr(f.args[1],f.args[2],f.args[3],f.args['c'],f.args['d'],f.args['s'])})[2] end;-- посчитать символы Trg = function(s,t,f,fi)-- Производит замену строк произвольной длины (если с fi, регистр не учитывает). -- Приоритет - по порядку в таблицах. for n,p in ipairs(t) do t[n] = {fi and mw.ustring.upper(p) or p,mw.ustring.len(p)} end local r,i,l,N = {},1,mw.ustring.len(s),0 while i<=l do (function() for n,p in ipairs(t) do if ( fi and mw.ustring.upper(mw.ustring.sub(s,i,i+p[2]-1)) or mw.ustring.sub(s,i,i+p[2]-1) ) == p[1] then table.insert(r,f[n]); i = i+p[2]; N=N+1; return end end table.insert(r,mw.ustring.sub(s,i,i)); i=i+1; return end)() end return table.concat(r),N end; trg = function(frame)--Работает с номерными аргументами шаблона,если задан параметр u, иначе со своими. -- Заменяет в первом аргументе аргументы 2, 4, 6... на аргументы 3, 5, 7... local tf, t, f, i= frame.args['u'] and frame.getParent() or f, {}, {}, 1; while tf.args[2*i] do t[tf.args[2*i]]=tf.args[2*i+1] or '' end return ( M.Trg(tf.args[1],t,f,(frame.args['i'] or '')~='') ) end; join = function (f) --объединяет нумерованные аргументы вызвавшего шаблона -- от from или 1 до to или первого отсутствующего -- через первый параметр invoke. Последний элемент можно присоединять иначе, задав второй параметр. -- По умолчанию ',' & 'и' -- Если 3-й параметр invoke — "s", строки из пробелов игнорируются; если "_", игнорируются пустые строки local t, tf, i = {}, f:getParent(), tonumber(f.args.from) or 1 local k,j,m = tonumber(f.args.to),i,f.args[3] while k and i<=k or tf.args[i] do if ( ({ ['_']=function(s)return s~=''end; ['s']=function(s)return not tostring(s):match("^%s*$")end })[m] or function() return true end )(tf.args[i]) then t[j]=tf.args[i]; j=j+1 end; i=i+1 end return mw.text.listToText(t,f.args[1],f.args[2] or f.args[1]) end } function M.formatRound(frame) --форматирует число, чтобы оно имело order знаков после запятой return string.format("%0."..frame.args[2].."f",tonumber(frame.args[1])); end -- если строка s содержит число, увеличивает первое такое число на n, иначе возращает пустую строку. -- если число начинается на 0, то увеличенное число будет содержать по крайне мере столько цифр сколько исходное. function M.increase(s, n) local a,b,c = string.match(s, "([^0-9]*)([0-9]+)(.*)") if b==nil then return s end local num = tonumber(b) + n if b:sub(1,1)=='0' then b = string.format("%0"..b:len().."d", num) else b=num end return a .. b .. c end function M.ucfirst(frame ) local s = mw.text.trim( frame.args[1] or "" ) local s1 = "" -- if it's a list chop off and (store as s1) everything up to the first <li> local lipos = string.find(s, "<li>" ) if lipos then s1 = string.sub(s, 1, lipos + 3) s = string.sub(s, lipos + 4) end -- s1 is either "" or the first part of the list markup, so we can continue -- and prepend s1 to the returned string local letterpos if string.find(s, "^%[%[[^|]+|[^%]]+%]%]") then -- this is a piped wikilink, so we capitalise the text, not the pipe local _ _, letterpos = string.find(s, "|%A*%a") -- find the first letter after the pipe else letterpos = string.find(s, '%a') end if letterpos then local first = string.sub(s, 1, letterpos - 1) local letter = string.sub(s, letterpos, letterpos) local rest = string.sub(s, letterpos + 1) return s1 .. first .. string.upper(letter) .. rest else return s1 .. s end end return M 1d51eb45a573b689485dad672c0968c18ec3b342 Шаблон:Карточка/официальное название 10 169 380 2020-02-29T12:06:43Z ruwiki>Helgo13 0 Защитил страницу [[Шаблон:Карточка/официальное название]]: критический шаблон или модуль ([Редактирование=только администраторы] (бессрочно) [Переименование=только администраторы] (бессрочно)) wikitext text/x-wiki {{wikidata|p1448[language!:ru]|{{{1|}}}|separator=<br>|conjunction=<br>|monolingualLangTemplate=lang|from={{{from|}}}}}<noinclude>{{doc}}</noinclude> 708a700c58a199343531d8fb3eec7ee897e92732 Модуль:Wikidata/P512 828 286 733 2020-06-16T04:56:58Z ruwiki>Ghuron 0 выключаем категоризацию для докторов философии https://ru.wikipedia.org/w/index.php?diff=107578910 Scribunto text/plain local p = {} --[[ Функция формирует строку с викиразметкой для переданного свойства Принимает: объект контекста для вызова форматтеров и таблицу настройек Возвращает: вики-форматированную строку ]] function p.formatAcademicDegree( context, options ) if ( not context ) then error( 'context not specified' ); end; if ( not options ) then error( 'options not specified' ); end; if ( not options.entity ) then error( 'options.entity missing' ); end; local claims = context.selectClaims( options, options.property ); if (claims == nil) then return '' end local blackList = p.getPreviousDegrees( claims ) local formattedClaims = {} for i, claim in ipairs(claims) do if (claim.mainsnak.datavalue and not blackList[claim.mainsnak.datavalue.value['numeric-id']]) then local formattedStatement = context.formatStatement( options, claim ) if (formattedStatement) then formattedStatement = '<span class="wikidata-claim"' .. ' data-wikidata-property-id="' .. string.upper( options.property ) .. '" data-wikidata-claim-id="' .. claim.id .. '">' .. formattedStatement .. '</span>' if (claim.qualifiers) then formattedStatement = formattedStatement .. p.formatQualifier( context, options, claim.qualifiers.P585 ) end formattedStatement = formattedStatement .. p.formatCorrespondingCategory( claim ) table.insert( formattedClaims, formattedStatement ) end end end -- создание текстовой строки со списком оформленых заявлений из таблицы return mw.text.listToText( formattedClaims, options.separator, options.conjunction ); end --[[ Функция помещает в скобки текст первого квалификатора из переданной таблицы Принимает: объект контекста для вызова форматтеров, таблицу настроеки и таблицу квалификаторов Возвращает: отформатированная строка с квалификатором ]] function p.formatQualifier( context, options, qualifiers ) if (qualifiers~=nil and qualifiers[1] ~= nil) then return ' (' .. context.formatSnak( options, qualifiers[1] ) .. ')' end return '' end --[[ Функция формирует список соответствующих ученых степеней нижней ступени (P155) Например, для "доктор искусствоведения" это будет "кандидат искусствоведения" Принимает: объект таблицу сущностей - академических степеней персоны (P512) Возвращает: объект таблицу идентификаторов степеней нижней ступени ]] function p.getPreviousDegrees( claims ) -- Пока нет нормальной возможности загружать элементы c кэшем -- снаружи Module:Wikidata, мы эти соответствия захардкодим (без Q) local correspondingCandidates = { [16698078] = 19610224, -- архитектор [17281188] = 19610186, -- биолог [17281187] = 19610187, -- ветеринар [17281186] = 19610193, -- военный [16698080] = 19610195, -- географ [16698082] = 19610197, -- гео-мин [17281180] = 18523814, -- искусствовед [12101789] = 18523811, -- историк [16698084] = 19610200, -- культуролог [17281165] = 19610203, -- медик [17281161] = 19610206, -- педагог [12101787] = 4212319, -- политолог [17281156] = 19610208, -- психолог [17281153] = 19610210, -- сель-хоз [17281152] = 19610212, -- социолог [17281125] = 18071588, -- техник [17281115] = 19610228, -- фармацевт [17281097] = 18002832, -- физ-мат [17281087] = 19603970, -- филолог [17281084] = 19603972, -- философ [17281079] = 19610312, -- химик [17281072] = 17744738, -- экономист [18745564] = 19610320 -- юрист } local previousElements = {} for i, claim in ipairs(claims) do if(claim.mainsnak.datavalue) then local entityId = claim.mainsnak.datavalue.value['numeric-id'] if (entityId) then if correspondingCandidates[entityId] then previousElements[correspondingCandidates[entityId]] = true end end end end return previousElements end --[[ Функция формирует вики-разметку категории, соответствующей ученой степени Принимает: объект таблицу утверждения Возвращает: строку оформленного текста либо пустую строку ]] function p.formatCorrespondingCategory (claim) if ( not claim ) then return '' end; if ( not claim.mainsnak ) then return '' end; if claim.mainsnak.datavalue.value['numeric-id'] == 752297 then return '' end local label = mw.wikibase.label("Q" .. claim.mainsnak.datavalue.value['numeric-id']) if not label then label = '' end local result, changes = string.gsub(label, "доктор ", "Категория:Доктора ") if (changes == 1) then return '[[' .. result .. ']]' end result, changes = string.gsub(label, "кандидат ", "Категория:Кандидаты ") if (changes == 1) then return '[[' .. result .. ']]' end return '' end return p dea2568f9f334dcfc745eca69d76f89255ac1b2c Модуль:Separated entries 828 158 358 2020-07-05T06:33:20Z ruwiki>Serhio Magpie 0 + newline Scribunto text/plain -- This module takes positional parameters as input and concatenates them with -- an optional separator. The final separator (the "conjunction") can be -- specified independently, enabling natural-language lists like -- "foo, bar, baz and qux". local compressSparseArray = require('Module:TableTools').compressSparseArray local p = {} function p._main(args) local separator = args.separator -- Decode (convert to Unicode) HTML escape sequences, such as "&#32;" for space. and mw.text.decode(args.separator) or '' local conjunction = args.conjunction and mw.text.decode(args.conjunction) or separator -- Discard named parameters. local values = compressSparseArray(args) return mw.text.listToText(values, separator, conjunction) end local function makeInvokeFunction(separator, conjunction) return function (frame) local args = require('Module:Arguments').getArgs(frame) args.separator = separator or args.separator args.conjunction = conjunction or args.conjunction return p._main(args) end end p.main = makeInvokeFunction() p.br = makeInvokeFunction('<br />') p.newline = makeInvokeFunction('\n') p.comma = makeInvokeFunction(mw.message.new('comma-separator'):plain()) return p 33a68f0a46d62c42b6523a548f0f881e82ecfe58 Шаблон:Wikidata number switch 10 134 310 2020-07-12T09:21:12Z ruwiki>Serhio Magpie 0 Проверка - если ничего нет из первых трёх параметров, ничего и не выводить wikitext text/x-wiki {{#if: {{{3|}}} | {{#if: {{{5|}}} | {{{5|}}} | {{{3|}}} }} | {{#if: {{{2|}}} | {{#if: {{{4|}}} | {{{4|}}} | {{{2|}}} }} | {{#if: {{{1|}}} | {{#if: {{{4|}}}{{{5|}}} | {{#if: {{wikidata|{{{1|}}}|property-module=Wikidata/count|property-function=isMultiple|from={{{from|}}}}} | {{{5|}}} | {{{4|}}} }} | {{wikidata|{{{1|}}}|from={{{from|}}}}} }} }} }} }}<noinclude> {{doc}} </noinclude> 7541bb47e73905a8ee240baa1dab1801f9f7b166 Модуль:Uses Wikidata 828 303 767 2020-09-04T07:07:02Z ruwiki>QBA-bot 0 Защитил страницу [[Модуль:Uses Wikidata]]: критический шаблон или модуль (каскадная защита) ([Редактирование=только автоподтверждённые] (бессрочно) [Переименование=только автоподтверждённые] (бессрочно)) Scribunto text/plain local p = {} local function incat( name, label, dot ) local incat = '' if not dot then dot = '' end local pincat = mw.site.stats.pagesInCategory( name, all ) if pincat ~= 0 then incat = "[[:К:" .. name .. "|" .. label .. tostring( pincat ) .. "]]" .. dot end return incat end local function trackingcats(p_num) local result = incat("ВП:" .. p_num .. ":використовується", "'''U:'''", "•") .. incat("ВП:" .. p_num .. ":відсутня", "'''<s>U:'''", "</s>•") .. incat("Вікідані:" .. p_num .. ":відсутня", "'''<s>D:'''", "</s>•") .. incat("Вікідані:" .. p_num .. ":відрізняється", "'''↑↓:'''") if result ~= "" then return "[<span></span>" .. result .. "]" else return "" end end function p.usesProperty(frame) local parent = frame.getParent(frame) local result = '' local ii = 1 while true do local p_num = "" if parent.args[ii] or frame.args[ii] then p_num = mw.text.trim(string.upper(parent.args[ii] or frame.args[ii])) end if p_num ~= "" then local label = mw.wikibase.label(p_num) or "БЕЗ НАЗВИ" result = result .. "<li><b><i>[[d:Property:" .. p_num .. "|<small>" .. p_num .. "</small>:" .. label .. "]]</i></b> {[[d:Property talk:" .. p_num .. "|обс]]•[[d:Special:WhatLinksHere/Property:" .. p_num .. "|исп]]}" .. trackingcats(p_num) .. "</li>" ii = ii + 1 else break end end return result end return p 8a066acc434e0611d04134bb82a5fdd9d4fb5f9f Шаблон:Карточка/блок 10 157 356 2020-10-20T13:56:13Z ruwiki>Wikisaurus 0 Wikisaurus переименовал страницу [[Шаблон:Фрагмент таблицы]] в [[Шаблон:Карточка/блок]]: унификация с другими шаблонами для создания частей карточки wikitext text/x-wiki <includeonly>{{#invoke:Infobox|renderLines}}</includeonly><noinclude>{{doc}}</noinclude> b76f4bc95a8a44fea1fa0f577d84111b51ce1385 Шаблон:Переписать шаблон 10 190 426 2020-10-20T14:22:06Z ruwiki>Wikisaurus 0 wikitext text/x-wiki {{ombox |type = style |text = '''Этот шаблон следует переписать{{#if: {{{меташаблон|}}} | &nbsp;с использованием меташаблона {{tl|{{{меташаблон}}}}} }}.''' <div style="font-size:95%;">{{#if: {{{меташаблон|}}} | Использование меташаблонов позволяет более полно использовать возможности шаблонов (см. [[Википедия:Рекомендации по созданию шаблонов]])|См. также [[Википедия:Рекомендации по созданию шаблонов]].}}</div> }}<includeonly>{{no-doc|nocat={{{nocat|}}}|{{#switch: {{lc: {{{меташаблон|}}} }} | карточка = [[Категория:Википедия:Шаблоны для перевода на карточку]] | навигационная таблица = [[Категория:Википедия:Шаблоны для перевода на навигационную таблицу]] | статья проекта = [[Категория:Википедия:Шаблоны для перевода на статью проекта]] | ае | административная единица = [[Категория:Википедия:Шаблоны для перевода на шаблон АЕ]] | [[Категория:Википедия:Шаблоны к переработке]] }} {{#switch: {{lc: {{{меташаблон|}}} }} | карточка | карточка персонажа | ае | административная единица | воинское формирование ссср | карточка/блок = [[Категория:Шаблоны-карточки по алфавиту]] }} }}</includeonly><noinclude>{{doc}}</noinclude> cb8733e779fa70731f445053204e92dc5afa0ebb Модуль:Transclude 828 144 330 2020-11-17T12:38:34Z ruwiki>Wikisaurus 0 пропускать пустые параметры в forall и join Scribunto text/plain local p={} -- Вызывает внутренний шаблон с аргументами объемлющего шаблона function p.call(frame) local template = frame.args[1] local args = frame:getParent().args return frame:expandTemplate{ title=template, args=args } end -- Общая реализация для forall и call local function forallImpl(args, separator, conjunction, func) -- нумерованные ключи из args local keys = {} -- перебор в произвольном порядке, даже для нумерованных ключей for key, value in pairs(args) do if type(key) == 'number' and value and value ~= '' then table.insert(keys, key) end end table.sort(keys) local results = {} for _, key in ipairs(keys) do local value = func(args[key]) table.insert(results, value) end return mw.text.listToText(results, separator, conjunction) end -- Вызывает внутренний шаблон, передавая ему нумерованные параметры объемлющего шаблона по-одному function p.forall(frame) local template = frame.args[1] local separator = frame.args.separator or '' local conjunction = frame.args.conjunction or separator local args = frame:getParent().args local func = function(value) return frame:expandTemplate{ title = template, args = {value} } -- или другой frame? end return forallImpl(args, separator, conjunction, func) end -- Берёт нумерованные аргументы объемлющего шаблона и склеивает их в единую строку function p.join(frame) local separator = frame.args[1] or '' local conjunction = frame.args[2] or separator local args = frame:getParent().args local func = function(value) return value end return forallImpl(args, separator, conjunction, func) end -- Служебная функция: удаляет дубликаты из отсортированного массива с нумерованными индексами local function deleteDuplicates(args) local res = {} for key, value in pairs(args) do if args[key+1] ~= value then table.insert(res, value) end end return res end -- Вызывает внутренний шаблон несколько раз, передавая в него блоки аргументов объемлющего шаблона function p.npc(frame) local args = frame:getParent().args local templateFrame = frame:getParent() local template = frame.args[1] -- определение, блоки аргументов с какими номерами нужны: -- если в объемлющем шаблоне есть "параметр12" и в вызове модуля есть "параметр", то вызывается 12-й блок local nums = {} for key, _ in pairs(args) do local main, num = string.match(key, '^(.-)%s*(%d*)$') num = tonumber(num) -- учитывать "параметр12", только если задано "параметр" if num and frame.args[main] then table.insert(nums, num) end end table.sort(nums) nums = deleteDuplicates(nums) -- проходить по нужным номерам блоков по возрастанию и однократно -- подставлять в шаблон: -- 1. общие аргументы данного модуля -- 2. аргументы объемлющего шаблона вида "параметр12" как "параметр" в 12-й блок local results = {} for _, blockNum in ipairs(nums) do -- общие аргументы модуля, которые передаются в каждый блок local blockArgs = mw.clone(frame.args) -- metatable ломает expandTemplate setmetatable(blockArgs, nil) for key, value in pairs(args) do local main, num = string.match(key, '^(.-)%s*(%d*)$') num = tonumber(num) -- передавать "параметр12" как "параметр" в 12-й блок, только если есть "параметр" в вызове модуля if blockNum == num and frame.args[main] then blockArgs[main] = value end end local blockText = templateFrame:expandTemplate{ title=template; args=blockArgs } table.insert(results, blockText) end return table.concat(results) end -- Действует аналогично forall по числовой переменной, изменяющейся (по умолчанию, от 1) до f.args[2]. function p.cycle(f) local tf,ac,op=f:getParent(), {}, f.args.output or 'inline'; local sep=''; if op == 'newline' then sep='\n'; end for p,k in pairs(f.args) do if type(p)=='number' then if p>2 then ac[p-1]=k end else ac[p]=k end end local s,fh = f.args[2]:match('^%s*(%-?%d+)%s*%.%.') or 1, f.args[2]:match('%.%.%s*(%S.*)%s*$') or f.args[2] or ''; fh=tonumber(fh) or fh:match('^%s*(.-)%s*$'); s=tonumber(s); local acr={}; if not s then error('Начало цикла «'..s..'» — не число') end local function dc(order) local r=tf:expandTemplate{ title=f.args[1]; args={s,unpack(ac)} } if order == 'desc' then s=s-1; else s=s+1; end if r~='' then table.insert(acr,r); return r end end if type(fh)=='number' then if fh > s then while s<=fh do dc('asc') end else while s>=fh do dc('desc') end end elseif fh~='' then while tf:expandTemplate{ title=fh; args={s,unpack(ac)} } do dc('asc') end else while dc('asc') do end end return table.concat(acr, sep) end return p c17cfab4cebc23157f5ab8d18c7e4f5c273bfa59 Шаблон:Пример шаблона 10 300 761 2020-12-04T10:56:35Z ruwiki>QBA-bot 0 Защитил страницу [[Шаблон:Пример шаблона]]: критический шаблон или модуль (каскадная защита) ([Редактирование=только автоподтверждённые] (бессрочно) [Переименование=только автоподтверждённые] (бессрочно)) wikitext text/x-wiki {{#invoke:TemplateDataDoc|generateExample|{{#if:{{{1|}}}|{{{1}}}|{{BASEPAGENAME}}}}}}<noinclude>{{doc}}</noinclude> 4675b6574c5d274f0525e41569d31a0a4881168f Шаблон:Карточка/изображение 10 213 474 2021-01-23T04:16:05Z ruwiki>Serhio Magpie 0 Класс «media-caption» для подписи wikitext text/x-wiki <includeonly>{{#if:{{{1|}}}| {{#switch:{{{1|}}} |-=- |none= |нет= |{{#switch:{{str left|{{{1|}}}|1}} |[|<|{|={{{1|}}} |[[Файл:{{{1|}}}|{{#if:{{{size|{{{2|}}}}}}|{{#ifeq:{{str rightc|{{{size|{{{2|}}}}}}|2}}|px|{{{size|{{{2|}}}}}}|{{#ifeq:{{str rightc|{{{size|{{{2|}}}}}}|3}}|пкс|{{{size|{{{2|}}}}}}|{{{size|{{{2|}}}}}}px}}}}|274x400px}}{{#if:{{{caption|}}}|{{!}}{{{caption|}}}}}|frameless{{#if:{{{border|}}}|{{!}}border}}{{#if:{{{alt|}}}|{{!}}alt={{{alt|}}}}}]] }}{{#if:{{{caption|}}} |<span class="media-caption" style="display:block;">{{{caption|}}}</span> }} }} }}</includeonly><!-- -->{{#if: {{{2|}}} | [[Категория:Википедия:Страницы с использованием устаревшего формата параметра Карточка/изображение]] }}<!-- -->{{#ifeq: {{str find|{{{size|{{{2|}}}}}}|pxpx}} | -1 || [[Категория:Википедия:Изображение с pxpx в размере]] }}<noinclude>{{doc}}</noinclude> c54dd8fbf131f3bc584add9cd834eea7b4f45e43 Модуль:InfoboxImage 828 84 142 2021-01-23T04:17:21Z ruwiki>Serhio Magpie 0 Класс «media-caption» для подписи Scribunto text/plain -- Inputs: -- image - Can either be a bare filename (with or without the File:/Image: prefix) or a fully formatted image link -- size - size to display the image -- maxsize - maximum size for image -- sizedefault - default size to display the image if size param is blank -- alt - alt text for image -- title - title text for image -- border - set to yes if border -- center - set to yes, if the image has to be centered -- upright - upright image param -- suppressplaceholder - if yes then checks to see if image is a placeholder and suppresses it -- Outputs: -- Formatted image. -- More details available at the "Module:InfoboxImage/doc" page local i = {}; local yesno = require('Module:Yesno'); local placeholder_image = { "Blue - Replace this image female.svg", "Blue - Replace this image male.svg", "Female no free image yet.png", "Flag of None (square).svg", "Flag of None.svg", "Flag of.svg", "Green - Replace this image female.svg", "Green - Replace this image male.svg", "Image is needed female.svg", "Image is needed male.svg", "Location map of None.svg", "Male no free image yet.png", "Missing flag.png", "No flag.svg", "No free portrait.svg", "No portrait (female).svg", "No portrait (male).svg", "Red - Replace this image female.svg", "Red - Replace this image male.svg", "Replace this image female (blue).svg", "Replace this image female.svg", "Replace this image male (blue).svg", "Replace this image male.svg", "Silver - Replace this image female.svg", "Silver - Replace this image male.svg", } function i.IsPlaceholder(image) -- change underscores to spaces image = mw.ustring.gsub(image, "_", " "); -- if image starts with [[ then remove that and anything after | if mw.ustring.sub(image,1,2) == "[[" then image = mw.ustring.sub(image,3); image = mw.ustring.gsub(image, "([^|]*)|.*", "%1"); end -- Trim spaces image = mw.ustring.gsub(image, '^[ ]*(.-)[ ]*$', '%1'); -- remove file: or image: prefix if exists if mw.ustring.lower(mw.ustring.sub(image,1,5)) == "file:" then image = mw.ustring.sub(image,6); end if mw.ustring.lower(mw.ustring.sub(image,1,6)) == "image:" then image = mw.ustring.sub(image,7); end -- Trim spaces image = mw.ustring.gsub(image, '^[ ]*(.-)[ ]*$', '%1'); -- capitalise first letter image = mw.ustring.upper(mw.ustring.sub(image,1,1)) .. mw.ustring.sub(image,2); for i,j in pairs(placeholder_image) do if image == j then return true end end return false end function i.InfoboxImage(frame) local image = frame.args["image"]; if image == "" or image == nil then return ""; end if image == "&nbsp;" then return image; end if frame.args["suppressplaceholder"] == "yes" then if i.IsPlaceholder(image) == true then return ""; end end if mw.ustring.lower(mw.ustring.sub(image,1,5)) == "http:" then return ""; end if mw.ustring.lower(mw.ustring.sub(image,1,6)) == "[http:" then return ""; end if mw.ustring.lower(mw.ustring.sub(image,1,7)) == "[[http:" then return ""; end if mw.ustring.lower(mw.ustring.sub(image,1,6)) == "https:" then return ""; end if mw.ustring.lower(mw.ustring.sub(image,1,7)) == "[https:" then return ""; end if mw.ustring.lower(mw.ustring.sub(image,1,8)) == "[[https:" then return ""; end if mw.ustring.sub(image,1,2) == "[[" then -- search for thumbnail images and add to tracking cat if found if mw.title.getCurrentTitle().namespace == 0 and (mw.ustring.find(image, "|%s*thumb%s*[|%]]") or mw.ustring.find(image, "|%s*thumbnail%s*[|%]]")) then return image --.. "[[Категория:Страницы с миниатюрами в карточках]]"; else return image; end elseif mw.ustring.sub(image,1,2) == "{{" and mw.ustring.sub(image,1,3) ~= "{{{" then return image; elseif mw.ustring.sub(image,1,1) == "<" then return image; elseif mw.ustring.sub(image,1,5) == mw.ustring.char(127).."UNIQ" then -- Found strip marker at begining, so pass don't process at all return image; else local result = ""; local size = frame.args["size"]; local maxsize = frame.args["maxsize"]; local sizedefault = frame.args["sizedefault"]; local alt = frame.args["alt"]; local title = frame.args["title"]; local border = yesno(frame.args["border"]); local upright = frame.args["upright"] or ""; local center = yesno(frame.args["center"]); local caption = frame.args["caption"]; -- remove file: or image: prefix if exists if mw.ustring.lower(mw.ustring.sub(image,1,5)) == "file:" then image = mw.ustring.sub(image,6); end if mw.ustring.lower(mw.ustring.sub(image,1,6)) == "image:" then image = mw.ustring.sub(image,7); end if maxsize ~= "" and maxsize ~= nil then -- if no sizedefault then set to maxsize if sizedefault == "" or sizedefault == nil then sizedefault = maxsize end -- check to see if size bigger than maxsize if size ~= "" and size ~= nil then local sizenumber = tonumber(mw.ustring.match(size,"%d*")) or 0; local maxsizenumber = tonumber(mw.ustring.match(maxsize,"%d*")); if sizenumber>maxsizenumber and maxsizenumber>0 then size = maxsize; end end end -- add px to size if just a number if (tonumber(size) or 0) > 0 then size = size .. "px"; end result = "[[File:" .. image; if size ~= "" and size ~= nil then result = result .. "|" .. size; elseif sizedefault ~= "" and sizedefault ~= nil then result = result .. "|" .. sizedefault; else result = result .. "|frameless"; end if center then result = result .. "|center" end if alt ~= "" and alt ~= nil then result = result .. "|alt=" .. alt; end if border then result = result .. "|border"; end if upright ~= "" then result = result .. "|upright=" .. upright; end if title ~= "" and title ~= nil then result = result .. "|" .. title; elseif alt ~= "" and alt ~= nil then result = result .. "|" .. alt; end result = result .. "]]"; if caption ~= "" and caption ~= nil then result = result .. '<span class="media-caption" style="display:block">' .. caption .. '</span>'; end return result; end end return i; ec0754cf3050a84a661c48656d091d291822e37d Модуль:Hash 828 168 378 2021-02-07T10:01:11Z ruwiki>Grain of sand 0 + list() для вывода списка доступных алгоритмов Scribunto text/plain local getArgs = require('Module:Arguments').getArgs local p = {} local function inTable(table, value) for k, v in pairs(table) do if v == value then return true end end return false end function p.list(frame) return table.concat(mw.hash.listAlgorithms(), '; ') end function p.main(frame) local args = getArgs(frame, { frameOnly = true }) local algorithm if not args[1] then return '<span class="error">Не указана строка для хеширования.</span>' end if args[2] then if not inTable(mw.hash.listAlgorithms(), args[2]) then return '<span class="error">Алгоритм хеширования ' .. args[2] .. ' не поддерживается, или вы неточно указали его имя. Используйте функцию <kbd>mw.hash.listAlgorithms()</kbd> для получения списка доступных алгоритмов.</span>' end algorithm = args[2] else -- Алгоритм выбран из соображений быстродействия (см. [[:en:Fowler–Noll–Vo hash function]]), -- 64-битная функция используется для уменьшения вероятности коллизий до пренебрежимо малой -- величины. Возможно, есть лучшая опция — проверяйте. algorithm = 'fnv164' end return mw.hash.hashValue(algorithm, args[1]) end return p 5d18513e574435f191164695449a620b031f93ec Шаблон:Module rating 10 94 454 2021-02-12T16:47:09Z ruwiki>Grain of sand 0 Grain of sand переименовал страницу [[Шаблон:Module rating]] в [[Шаблон:Рейтинг модуля]]: русский язык wikitext text/x-wiki #перенаправление [[Шаблон:Рейтинг модуля]] 0539367219fc11b0d7d42bed14b289f52d90e6f1 Модуль:Infocards/dateCat 828 278 717 2021-02-14T08:16:01Z ruwiki>WindEwriX 0 Защитил страницу [[Модуль:Infocards/dateCat]]: критический шаблон или модуль: включён в [[Модуль:Wikidata/date]] и [[Модуль:Infocards]] ([Редактирование=администраторы и инженеры] (бессрочно) [Переименование=администраторы и инженеры] (бессрочно)) Scribunto text/plain local p = {} p.categoryUnknownBirthDate = '[[Категория:Персоналии, чья дата рождения не установлена]]' p.categoryUnknownDeathDate = '[[Категория:Персоналии, чья дата смерти не установлена]]' p.categoryBigCurrentAge = '[[Категория:Персоналии с большим текущим возрастом]]' --бывш. [[Категория:Википедия:Статьи о персоналиях с большим текущим возрастом]] p.categoryNegativeAge = '[[Категория:Персоналии с отрицательным возрастом]]' -- p.categoryBigDeathAge = '[[Категория:Википедия:Статьи о персоналиях с большим возрастом во время смерти]]' //deleted -d.bratchuk 05-07-2016 p.categoryBiographiesOfLivingPersons = '[[Категория:Википедия:Биографии современников]]' p.categoryRecentlyDeceased = '[[Категория:Персоналии, умершие менее года назад]]' p.categoryManualWikification = '[[Категория:Википедия:Статьи с ручной викификацией дат в карточке]]' p.categoryNoBirthDate = '[[Категория:Персоналии без указанной даты рождения]]' --бывш. [[Категория:Википедия:Персоны без указанной даты рождения]] return p 6b27e44bc0a4aaafa42074ca16db92b13e4999d4 Шаблон:Doc/end 10 176 394 2021-02-14T18:18:13Z ruwiki>Putnik 0 для модулей предзагрузка нормально не работает wikitext text/x-wiki <includeonly></div> </div><templatestyles src="Шаблон:Doc/styles.css" />{{#ifexpr: {{NAMESPACENUMBER}} mod 2 = 1 <!-- Например, [[Обсуждение MediaWiki:Robots.txt]] --> | {{^|1em}} | <div class="ts-doc-footer plainlinks"> {{#ifeq: {{str left|{{PAGENAME}}|9}} | Песочница | | {{#ifeq: {{str rightc|{{PAGENAME}}|10}} | /песочница | | Во избежание поломок страниц, использующих этот {{#ifeq: {{NAMESPACE}} | Модуль | модуль | шаблон }}, экспериментируйте в [[Википедия:Правка и тестирование шаблонов в песочнице|песочнице]] <small style="font-style:normal;">({{#ifexist: {{FULLPAGENAME}}/песочница | [{{fullurl:{{FULLPAGENAME}}/песочница|action=edit}} редактировать] {{!}} [{{fullurl:Special:ComparePages|page1={{FULLPAGENAMEE}}&page2={{FULLPAGENAMEE}}/песочница}} разница] {{#ifexist: {{FULLPAGENAME}}/тесты | {{!}} [[{{FULLPAGENAME}}/тесты|тесты]] }} | {{#ifeq: {{NAMESPACE}} | Модуль | [{{fullurl:{{FULLPAGENAME}}/песочница|action=edit}} создать] | [{{fullurl:{{FULLPAGENAME}}/песочница|action=edit&preload=Шаблон:Doc/предзагрузка-песочница}} создать] {{!}} [{{fullurl:{{FULLPAGENAME}}/песочница|action=edit&preload=Шаблон:Doc/зеркало}} зеркало] }} }})</small> или {{#ifeq: {{NAMESPACE}} | Модуль | [[Модуль:Песочница|песочнице для модулей]] | своём [[ВП:ЛП|личном пространстве]] }}.<br> }} }}{{#ifexist: {{FULLPAGENAME}}/doc | Пожалуйста, добавляйте категории на подстраницу [[/doc]].&#32;}}[[Special:PrefixIndex/{{FULLPAGENAME}}/|Подстраницы этого {{#ifeq: {{NAMESPACE}} | Модуль | модуля | шаблона }}]]. </div> }}</includeonly><noinclude>{{doc}}</noinclude> 758a01a3d76e14ef14b2b0ee047ac47ddac8fd8e Шаблон:Tnav 10 219 486 2021-02-28T17:42:07Z ruwiki>Jack who built the house 0 дополнение wikitext text/x-wiki {{t|{{{1|}}}|nav|comment={{{comment|}}}}}<noinclude> {{doc-inline}} Это — обёртка для шаблона {{t|tl}}, предназначенная для использования в блоках навигации. Она передаёт в него флаг <code>nav</code> и комментарий в параметре {{para|comment}}. {{шаблоны для документирования}} {{doc-end}} [[Категория:Шаблоны:Ссылки на шаблоны]] [[Категория:Шаблоны:Для навигационных шаблонов]] </noinclude> 583d607aa213790ae32dda4018a413255493e42b Модуль:Color contrast 828 151 344 2021-03-01T22:40:23Z ruwiki>Grain of sand 0 local Scribunto text/plain -- -- This module implements -- {{Color contrast ratio}} -- {{Greater color contrast ratio}} -- {{ColorToLum}} -- {{RGBColorToLum}} -- local p = {} local HTMLcolor = mw.loadData( 'Module:Color contrast/colors' ) local function sRGB ( v ) if (v <= 0.03928) then v = v / 12.92 else v = math.pow((v+0.055)/1.055, 2.4) end return v end local function rgbdec2lum( R, G, B ) if ( 0 <= R and R < 256 and 0 <= G and G < 256 and 0 <= B and B < 256 ) then return 0.2126 * sRGB(R/255) + 0.7152 * sRGB(G/255) + 0.0722 * sRGB(B/255) else return '' end end local function hsl2lum( h, s, l ) if ( 0 <= h and h < 360 and 0 <= s and s <= 1 and 0 <= l and l <= 1 ) then local c = (1 - math.abs(2*l - 1))*s local x = c*(1 - math.abs( math.fmod(h/60, 2) - 1) ) local m = l - c/2 local r, g, b = m, m, m if( 0 <= h and h < 60 ) then r = r + c g = g + x elseif( 60 <= h and h < 120 ) then r = r + x g = g + c elseif( 120 <= h and h < 180 ) then g = g + c b = b + x elseif( 180 <= h and h < 240 ) then g = g + x b = b + c elseif( 240 <= h and h < 300 ) then r = r + x b = b + c elseif( 300 <= h and h < 360 ) then r = r + c b = b + x end return rgbdec2lum(255*r, 255*g, 255*b) else return '' end end local function color2lum( c ) if (c == nil) then return '' end -- whitespace c = c:match( '^%s*(.-)[%s;]*$' ) -- lowercase c = c:lower() -- first try to look it up local L = HTMLcolor[c] if (L ~= nil) then return L end -- convert from hsl if mw.ustring.match(c,'^hsl%([%s]*[0-9][0-9%.]*[%s]*,[%s]*[0-9][0-9%.]*%%[%s]*,[%s]*[0-9][0-9%.]*%%[%s]*%)$') then local h, s, l = mw.ustring.match(c,'^hsl%([%s]*([0-9][0-9%.]*)[%s]*,[%s]*([0-9][0-9%.]*)%%[%s]*,[%s]*([0-9][0-9%.]*)%%[%s]*%)$') return hsl2lum(tonumber(h), tonumber(s)/100, tonumber(l)/100) end -- convert from rgb if mw.ustring.match(c,'^rgb%([%s]*[0-9][0-9]*[%s]*,[%s]*[0-9][0-9]*[%s]*,[%s]*[0-9][0-9]*[%s]*%)$') then local R, G, B = mw.ustring.match(c,'^rgb%([%s]*([0-9][0-9]*)[%s]*,[%s]*([0-9][0-9]*)[%s]*,[%s]*([0-9][0-9]*)[%s]*%)$') return rgbdec2lum(tonumber(R), tonumber(G), tonumber(B)) end -- convert from rgb percent if mw.ustring.match(c,'^rgb%([%s]*[0-9][0-9%.]*%%[%s]*,[%s]*[0-9][0-9%.]*%%[%s]*,[%s]*[0-9][0-9%.]*%%[%s]*%)$') then local R, G, B = mw.ustring.match(c,'^rgb%([%s]*([0-9][0-9%.]*)%%[%s]*,[%s]*([0-9][0-9%.]*)%%[%s]*,[%s]*([0-9][0-9%.]*)%%[%s]*%)$') return rgbdec2lum(255*tonumber(R)/100, 255*tonumber(G)/100, 255*tonumber(B)/100) end -- remove leading # (if there is one) and whitespace c = mw.ustring.match(c, '^[%s#]*([a-f0-9]*)[%s]*$') -- split into rgb local cs = mw.text.split(c or '', '') if( #cs == 6 ) then local R = 16*tonumber('0x' .. cs[1]) + tonumber('0x' .. cs[2]) local G = 16*tonumber('0x' .. cs[3]) + tonumber('0x' .. cs[4]) local B = 16*tonumber('0x' .. cs[5]) + tonumber('0x' .. cs[6]) return rgbdec2lum(R, G, B) elseif ( #cs == 3 ) then local R = 16*tonumber('0x' .. cs[1]) + tonumber('0x' .. cs[1]) local G = 16*tonumber('0x' .. cs[2]) + tonumber('0x' .. cs[2]) local B = 16*tonumber('0x' .. cs[3]) + tonumber('0x' .. cs[3]) return rgbdec2lum(R, G, B) end -- failure, return blank return '' end function p._greatercontrast(args) local bias = tonumber(args['bias'] or '0') or 0 local v1 = color2lum(args[1] or '') local c2 = args[2] or '#FFFFFF' local v2 = color2lum(c2) local c3 = args[3] or '#000000' local v3 = color2lum(c3) local ratio1 = 0; local ratio2 = 0; if (type(v1) == 'number' and type(v2) == 'number') then ratio1 = (v2 + 0.05)/(v1 + 0.05) ratio1 = (ratio1 < 1) and 1/ratio1 or ratio1 end if (type(v1) == 'number' and type(v3) == 'number') then ratio2 = (v3 + 0.05)/(v1 + 0.05) ratio2 = (ratio2 < 1) and 1/ratio2 or ratio2 end return (ratio1 + bias > ratio2) and c2 or c3 end function p._ratio(args) local v1 = color2lum(mw.text.unstripNoWiki(args[1] or '')) local v2 = color2lum(mw.text.unstripNoWiki(args[2] or '')) if (type(v1) == 'number' and type(v2) == 'number') then -- v1 should be the brighter of the two. if v2 > v1 then v1, v2 = v2, v1 end return (v1 + 0.05)/(v2 + 0.05) else return args['error'] or '?' end end function p._styleratio(args) local style = (args[1] or ''):lower() local bg, fg = 'white', '#202122' local lum_bg, lum_fg = 1, 0.016 if args[2] then local lum = color2lum(args[2]) if lum ~= '' then bg, lum_bg = args[2], lum end end if args[3] then local lum = color2lum(args[3]) if lum ~= '' then fg, lum_fg = args[3], lum end end local slist = mw.text.split(style or '', ';') for k = 1, #slist do local s = slist[k] local k, v = s:match( '^[%s]*([^:]-):([^:]-)[%s;]*$' ) k = k or '' v = v or '' if (k:match('^[%s]*(background)[%s]*$') or k:match('^[%s]*(background%-color)[%s]*$')) then local lum = color2lum(v) if( lum ~= '' ) then bg, lum_bg = v, lum end elseif (k:match('^[%s]*(color)[%s]*$')) then local lum = color2lum(v) if( lum ~= '' ) then bg, lum_fg = v, lum end end end if lum_bg > lum_fg then return (lum_bg + 0.05)/(lum_fg + 0.05) else return (lum_fg + 0.05)/(lum_bg + 0.05) end end function p.lum(frame) return color2lum(frame.args[1] or frame:getParent().args[1]) end function p.ratio(frame) local args = frame.args[1] and frame.args or frame:getParent().args return p._ratio(args) end function p.styleratio(frame) local args = frame.args[1] and frame.args or frame:getParent().args return p._styleratio(args) end function p.greatercontrast(frame) local args = frame.args[1] and frame.args or frame:getParent().args return p._greatercontrast(args) end return p cce580326bee8eaf3c81df6c76c04a9a2909dfa2 Шаблон:Wikidata 10 261 683 2021-04-01T12:24:50Z ruwiki>MBH 0 [[ВП:Откат|откат]] правок [[Special:Contribs/Lê Lợi (bot)|Lê Lợi (bot)]] ([[UT:Lê Lợi (bot)|обс.]]) к версии Wikisaurus wikitext text/x-wiki <includeonly>{{#invoke:Wikidata|formatProperty|property={{{1|}}}|value={{{2|}}}}}</includeonly><noinclude>{{doc}}</noinclude> 9d3d422eca39504b018df6ec0bb047392a7aba7e Модуль:String 828 138 318 2021-05-06T07:16:24Z ruwiki>Alexei Kopylov 0 [[ВП:Откат|откат]] правок [[Special:Contribs/Alexei Kopylov|Alexei Kopylov]] ([[UT:Alexei Kopylov|обс.]]) к версии DonRumata Scribunto text/plain --[[ This module is intended to provide access to basic string functions. Most of the functions provided here can be invoked with named parameters, unnamed parameters, or a mixture. If named parameters are used, Mediawiki will automatically remove any leading or trailing whitespace from the parameter. Depending on the intended use, it may be advantageous to either preserve or remove such whitespace. Global options ignore_errors: If set to 'true' or 1, any error condition will result in an empty string being returned rather than an error message. error_category: If an error occurs, specifies the name of a category to include with the error message. The default category is [Category:Errors reported by Module String]. no_category: If set to 'true' or 1, no category will be added if an error is generated. Unit tests for this module are available at Module:String/tests. ]] local str = {} --[[ subcount This function returns the count of substring in source string. Usage: {{#invoke:String|subcount|source_string|substring|plain_flag}} OR {{#invoke:String|subcount|s=source_string|pattern=substring|plain=plain_flag}} Parameters s: The string to search pattern: The pattern or string to find within the string plain: A flag indicating that the substring should be understood as plain text. Defaults to true. If invoked using named parameters, Mediawiki will automatically remove any leading or trailing whitespace from the target string. ]] function str.subcount( frame ) local new_args = str._getParameters( frame.args, {'s', 'pattern', 'plain'} ); local s = new_args['s'] or ''; local plain_flag = str._getBoolean( new_args['plain'] or true ); local pattern = new_args['pattern'] or ''; if s == '' or pattern == '' then return 0; end if plain_flag then pattern = str._escapePattern( pattern ); end local _, count = mw.ustring.gsub(s, pattern, "") return count; end --[[ len This function returns the length of the target string. Usage: {{#invoke:String|len|target_string|}} OR {{#invoke:String|len|s=target_string}} Parameters s: The string whose length to report If invoked using named parameters, Mediawiki will automatically remove any leading or trailing whitespace from the target string. ]] function str.len( frame ) local new_args = str._getParameters( frame.args, {'s'} ); local s = new_args['s'] or ''; return mw.ustring.len( s ) end --[[ sub This function returns a substring of the target string at specified indices. Usage: {{#invoke:String|sub|target_string|start_index|end_index}} OR {{#invoke:String|sub|s=target_string|i=start_index|j=end_index}} Parameters s: The string to return a subset of i: The fist index of the substring to return, defaults to 1. j: The last index of the string to return, defaults to the last character. The first character of the string is assigned an index of 1. If either i or j is a negative value, it is interpreted the same as selecting a character by counting from the end of the string. Hence, a value of -1 is the same as selecting the last character of the string. If the requested indices are out of range for the given string, an error is reported. ]] function str.sub( frame ) local new_args = str._getParameters( frame.args, { 's', 'i', 'j' } ); local s = new_args['s'] or ''; local i = tonumber( new_args['i'] ) or 1; local j = tonumber( new_args['j'] ) or -1; local len = mw.ustring.len( s ); -- Convert negatives for range checking if i < 0 then i = len + i + 1; end if j < 0 then j = len + j + 1; end if i > len or j > len or i < 1 or j < 1 then return str._error( 'Значение индекса подстроки выходит за допустимые границы' ); end if j < i then return str._error( 'Неверный порядок индексов подстроки' ); end return mw.ustring.sub( s, i, j ) end --[[ This function implements that features of {{str sub old}} and is kept in order to maintain these older templates. ]] function str.sublength( frame ) local i = tonumber( frame.args.i ) or 0 local len = tonumber( frame.args.len ) return mw.ustring.sub( frame.args.s, i + 1, len and ( i + len ) ) end --[[ match This function returns a substring from the source string that matches a specified pattern. Usage: {{#invoke:String|match|source_string|pattern_string|start_index|match_number|plain_flag|nomatch_output}} OR {{#invoke:String|pos|s=source_string|pattern=pattern_string|start=start_index |match=match_number|plain=plain_flag|nomatch=nomatch_output}} Parameters s: The string to search pattern: The pattern or string to find within the string start: The index within the source string to start the search. The first character of the string has index 1. Defaults to 1. match: In some cases it may be possible to make multiple matches on a single string. This specifies which match to return, where the first match is match= 1. If a negative number is specified then a match is returned counting from the last match. Hence match = -1 is the same as requesting the last match. Defaults to 1. plain: A flag indicating that the pattern should be understood as plain text. Defaults to false. nomatch: If no match is found, output the "nomatch" value rather than an error. If invoked using named parameters, Mediawiki will automatically remove any leading or trailing whitespace from each string. In some circumstances this is desirable, in other cases one may want to preserve the whitespace. If the match_number or start_index are out of range for the string being queried, then this function generates an error. An error is also generated if no match is found. If one adds the parameter ignore_errors=true, then the error will be suppressed and an empty string will be returned on any failure. For information on constructing Lua patterns, a form of [regular expression], see: * http://www.lua.org/manual/5.1/manual.html#5.4.1 * http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Patterns * http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Ustring_patterns ]] function str.match( frame ) local new_args = str._getParameters( frame.args, {'s', 'pattern', 'start', 'match', 'plain', 'nomatch'} ); local s = new_args['s'] or ''; local start = tonumber( new_args['start'] ) or 1; local plain_flag = str._getBoolean( new_args['plain'] or false ); local pattern = new_args['pattern'] or ''; local match_index = math.floor( tonumber(new_args['match']) or 1 ); local nomatch = new_args['nomatch']; if s == '' then return str._error( 'Пустая строка поиска' ); end if pattern == '' then return str._error( 'Пустой шаблон поиска' ); end if math.abs(start) < 1 or math.abs(start) > mw.ustring.len( s ) then return str._error( 'Индекс начала поиска выходит за допустимые границы' ); end if match_index == 0 then return str._error( 'Индекс совпадения выходит за допустимые границы' ); end if plain_flag then pattern = str._escapePattern( pattern ); end local result if match_index == 1 then -- Find first match is simple case result = mw.ustring.match( s, pattern, start ) else if start > 1 then s = mw.ustring.sub( s, start ); end local iterator = mw.ustring.gmatch(s, pattern); if match_index > 0 then -- Forward search for w in iterator do match_index = match_index - 1; if match_index == 0 then result = w; break; end end else -- Reverse search local result_table = {}; local count = 1; for w in iterator do result_table[count] = w; count = count + 1; end result = result_table[ count + match_index ]; end end if result == nil then if nomatch == nil then return str._error( 'Совпадение не найдено' ); else return nomatch; end else return result; end end --[[ pos This function returns a single character from the target string at position pos. Usage: {{#invoke:String|pos|target_string|index_value}} OR {{#invoke:String|pos|target=target_string|pos=index_value}} Parameters target: The string to search pos: The index for the character to return If invoked using named parameters, Mediawiki will automatically remove any leading or trailing whitespace from the target string. In some circumstances this is desirable, in other cases one may want to preserve the whitespace. The first character has an index value of 1. If one requests a negative value, this function will select a character by counting backwards from the end of the string. In other words pos = -1 is the same as asking for the last character. A requested value of zero, or a value greater than the length of the string returns an error. ]] function str.pos( frame ) local new_args = str._getParameters( frame.args, {'target', 'pos'} ); local target_str = new_args['target'] or ''; local pos = tonumber( new_args['pos'] ) or 0; if pos == 0 or math.abs(pos) > mw.ustring.len( target_str ) then return str._error( 'Значение индекса строки выходит за допустимые границы' ); end return mw.ustring.sub( target_str, pos, pos ); end --[[ str_find This function duplicates the behavior of {{str_find}}, including all of its quirks. This is provided in order to support existing templates, but is NOT RECOMMENDED for new code and templates. New code is recommended to use the "find" function instead. Returns the first index in "source" that is a match to "target". Indexing is 1-based, and the function returns -1 if the "target" string is not present in "source". Important Note: If the "target" string is empty / missing, this function returns a value of "1", which is generally unexpected behavior, and must be accounted for separatetly. ]] function str.str_find( frame ) local new_args = str._getParameters( frame.args, {'source', 'target'} ); local source_str = new_args['source'] or ''; local target_str = new_args['target'] or ''; if target_str == '' then return 1; end local start = mw.ustring.find( source_str, target_str, 1, true ) if start == nil then start = -1 end return start end --[[ find This function allows one to search for a target string or pattern within another string. Usage: {{#invoke:String|find|source_str|target_string|start_index|plain_flag}} OR {{#invoke:String|find|source=source_str|target=target_str|start=start_index|plain=plain_flag}} Parameters source: The string to search target: The string or pattern to find within source start: The index within the source string to start the search, defaults to 1 plain: Boolean flag indicating that target should be understood as plain text and not as a Lua style regular expression, defaults to true If invoked using named parameters, Mediawiki will automatically remove any leading or trailing whitespace from the parameter. In some circumstances this is desirable, in other cases one may want to preserve the whitespace. This function returns the first index >= "start" where "target" can be found within "source". Indices are 1-based. If "target" is not found, then this function returns 0. If either "source" or "target" are missing / empty, this function also returns 0. This function should be safe for UTF-8 strings. ]] function str.find( frame ) local new_args = str._getParameters( frame.args, {'source', 'target', 'start', 'plain' } ); local source_str = new_args['source'] or ''; local pattern = new_args['target'] or ''; local start_pos = tonumber(new_args['start']) or 1; local plain = new_args['plain'] or true; if source_str == '' or pattern == '' then return 0; end plain = str._getBoolean( plain ); local start = mw.ustring.find( source_str, pattern, start_pos, plain ) if start == nil then start = 0 end return start end --[[ replace This function allows one to replace a target string or pattern within another string. Usage: {{#invoke:String|replace|source_str|pattern_string|replace_string|replacement_count|plain_flag}} OR {{#invoke:String|replace|source=source_string|pattern=pattern_string|replace=replace_string| count=replacement_count|plain=plain_flag}} Parameters source: The string to search pattern: The string or pattern to find within source replace: The replacement text count: The number of occurences to replace, defaults to all. plain: Boolean flag indicating that pattern should be understood as plain text and not as a Lua style regular expression, defaults to true ]] function str.replace( frame ) local new_args = str._getParameters( frame.args, {'source', 'pattern', 'replace', 'count', 'plain' } ); local source_str = new_args['source'] or ''; local pattern = new_args['pattern'] or ''; local replace = new_args['replace'] or ''; local count = tonumber( new_args['count'] ); local plain = new_args['plain'] or true; if source_str == '' or pattern == '' then return source_str; end plain = str._getBoolean( plain ); if plain then pattern = str._escapePattern( pattern ); replace = mw.ustring.gsub( replace, "%%", "%%%%" ); --Only need to escape replacement sequences. end local result; if count ~= nil then result = mw.ustring.gsub( source_str, pattern, replace, count ); else result = mw.ustring.gsub( source_str, pattern, replace ); end return result; end --[[ This function adds support for escaping parts of the patterns when using [plain=false]. ]] function str.escape( frame ) local new_args = str._getParameters( frame.args, {'pattern' } ); local pattern = new_args['pattern'] or ''; local result = ''; result = str._escapePattern( pattern ); return result; end --[[ Internal compare string function ]] function str._strcmp(a , b) local s1c = mw.ustring.gcodepoint( a ); local s2c = mw.ustring.gcodepoint( b ); while true do local c1 = s1c(); local c2 = s2c(); if c1 == nil then if c2 == nil then return 0 else return -1 end else if c2 ~= nil then if c1 ~= c2 then return c1 < c2 and -1 or 1 end else return 1 end end end return 0 end --[[ compare This function compare two UTF-8 strings Usage: {{#invoke:String|compare|str1|str2}} Returns: 0 - if strings are equal 1 - if st1 > str2 -1 - if str1 < str2 ]] function str.compare(frame) local str1 = frame.args[1] or ''; local str2 = frame.args[2] or ''; return str._strcmp(str1 , str2) end --[[ simple function to pipe string.rep to templates. ]] function str.rep( frame ) local repetitions = tonumber( frame.args[2] ) if not repetitions then return str._error( 'функция rep ожидает число во втором параметре, а получено "' .. ( frame.args[2] or '' ) .. '"' ) end return string.rep( frame.args[1] or '', repetitions ) end --[[ Helper function that populates the argument list given that user may need to use a mix of named and unnamed parameters. This is relevant because named parameters are not identical to unnamed parameters due to string trimming, and when dealing with strings we sometimes want to either preserve or remove that whitespace depending on the application. ]] function str._getParameters( frame_args, arg_list ) local new_args = {}; local index = 1; local value; for i,arg in ipairs( arg_list ) do value = frame_args[arg] if value == nil then value = frame_args[index]; index = index + 1; end new_args[arg] = value; end return new_args; end --[[ Helper function to handle error messages. ]] function str._error( error_str ) local frame = mw.getCurrentFrame(); local error_category = frame.args.error_category or 'Страницы с ошибками модуля String'; local ignore_errors = frame.args.ignore_errors or false; local no_category = frame.args.no_category or false; if str._getBoolean(ignore_errors) then return ''; end local error_str = '<strong class="error">Ошибка модуля String: ' .. error_str .. '</strong>'; if error_category ~= '' and not str._getBoolean( no_category ) then error_str = '[[Категория:' .. error_category .. ']]' .. error_str; end return error_str; end --[[ Helper Function to interpret boolean strings ]] function str._getBoolean( boolean_str ) local boolean_value; if type( boolean_str ) == 'string' then boolean_str = boolean_str:lower(); if boolean_str == 'false' or boolean_str == 'no' or boolean_str == '0' or boolean_str == '' then boolean_value = false; else boolean_value = true; end elseif type( boolean_str ) == 'boolean' then boolean_value = boolean_str; else error( 'Логическое значение не найдено' ); end return boolean_value end --[[ Helper function that escapes all pattern characters so that they will be treated as plain text. ]] function str._escapePattern( pattern_str ) return mw.ustring.gsub( pattern_str, "([%(%)%.%%%+%-%*%?%[%^%$%]])", "%%%1" ); end return str b4a4e099d7fab23576bae7af327a44c87d13f9cb Шаблон:Карточка/импортёр/doc 10 258 676 2021-05-18T13:57:26Z ruwiki>Jaguar K 0 wikitext text/x-wiki {{docpage}} {{Импортёр шаблона-карточки||en|Infobox}} Этот подстановочный шаблон используется для быстрого перевода параметров карточек из английской Википедии. Если у вас не получается добиться подстановкой данного шаблона правильного переноса шаблона-карточки из английского раздела, пожалуйста, обратитесь [[Википедия:Форум/Технический|на технический форум]] за помощью в адаптации. 456ee3241716a284eec9a77f6d33a397f9f6181c Модуль:Hatnote 828 79 130 2021-05-23T00:33:16Z ruwiki>Grain of sand 0 по [[Обсуждение модуля:Hatnote#navigation-not-searchable|запросу на СО]] от [[u:Lockal|Lockal]] Scribunto text/plain local get_args = require('Module:Arguments').getArgs local mError local yesno = function (v) return require('Module:Yesno')(v, true) end local p, tr = {}, {} local current_title = mw.title.getCurrentTitle() local tracking_categories = { no_prefix = 'Википедия:Страницы с модулем Hatnote без указания префикса', no_links = 'Википедия:Страницы с модулем Hatnote без ссылок', red_link = 'Википедия:Страницы с модулем Hatnote с красной ссылкой', bad_format = 'Википедия:Страницы с модулем Hatnote с некорректно заполненными параметрами', unparsable_link = 'Википедия:Страницы с модулем Hatnote с нечитаемой ссылкой', formatted = 'Википедия:Страницы с модулем Hatnote с готовым форматированием', } local function index(t1, t2) return setmetatable(t1, {__index = t2}) end local function concat(e1, e2) return tostring(e1) .. tostring(e2) end function tr.define_categories(tracked_cases) local categories = setmetatable({}, { __tostring = function (self) return table.concat(self) end, __concat = concat }) function categories:add(element, nocat) if not nocat then local cat_name if tracked_cases and tracked_cases[element] then cat_name = tracked_cases[element] else cat_name = element end table.insert(self, string.format('[[Категория:%s]]', cat_name)) end end return categories end function tr.error(msg, categories, preview_only) local current_frame = mw.getCurrentFrame() local parent_frame = current_frame:getParent() local res_frame_title = parent_frame and parent_frame:getTitle() ~= current_title.prefixedText and parent_frame:getTitle() or current_frame:getTitle() if not preview_only or current_frame:preprocess('{{REVISIONID}}') == '' then mError = require('Module:Error') return mError.error{ tag = 'div', string.format('Ошибка в [[%s]]: %s.' .. (preview_only and '<br><small>Это сообщение показывается только во время предпросмотра.</small>' or ''), res_frame_title, msg) } .. categories else return categories end end function p.parse_link(frame) local args = get_args(frame) local link = args[1]:gsub('\n', '') local label link = mw.text.trim(link:match('^%[%[([^%]]+)%]%]$') or link) if link:sub(1, 1) == '/' then label = link link = current_title.prefixedText .. link end link = link:match(':?(.+)') if link:match('|') then link, label = link:match('^([^%|]+)%|(.+)$') end if not mw.title.new(link) then return nil, nil end return link, label end function p.format_link(frame) -- {{ссылка на раздел}} local args = get_args(frame) local link, section, label = args[1], args[2], args[3] if not link then link = current_title.prefixedText if section then link = '#' .. section label = label or '§&nbsp;' .. section end else local parsed_link, parsed_label = p.parse_link{link} if parsed_link then link = parsed_link else return link end if section and not link:match('#') then link = link .. '#' .. section if parsed_label then parsed_label = parsed_label .. '#' .. section end end label = (label or parsed_label or link):gsub('^([^#]-)#(.+)$', '%1 §&nbsp;%2') end if label and label ~= link then return string.format('[[:%s|%s]]', link, label) else return string.format('[[:%s]]', link) end end function p.remove_precision(frame) -- {{без уточнения}} local args = get_args(frame) local title = args[1] return title:match('^(.+)%s+%b()$') or title end function p.is_disambig(frame) local args = get_args(frame) local title = args[1] local page = mw.title.new(title) if not page or not page.exists or mw.title.equals(page, current_title) then return false end local page_content = page:getContent() local mw_list_content = mw.title.new('MediaWiki:Disambiguationspage'):getContent() local lang = mw.language.getContentLanguage() for template in mw.ustring.gmatch(mw_list_content, '%*%s?%[%[Шаблон:([^%]]+)') do if page_content:match('{{' .. template) or page_content:match('{{' .. lang:lcfirst(template)) then return true end end return false end function p.list(frame) local args = get_args(frame, {trim = false}) local list_sep = args.list_sep or args['разделитель списка'] or ', ' local last_list_sep = yesno(args.natural_join) ~= false and ' и ' or list_sep local links_ns = args.links_ns or args['ПИ ссылок'] local bold_links = yesno(args.bold_links or args['ссылки болдом']) local res_list = {} local tracked = { red_link = false, bad_format = false, formatted = false, unparsable_link = false } local i = 1 while args[i] do local link = args[i] local label = args['l' .. i] local element = '' if link:match('<span') then -- TODO: переписать tracked.formatted = true element = link -- for {{не переведено}} else local bad_format = (link:match('|') or link:match('[%[%]]')) ~= nil local parsed_link, parsed_label = p.parse_link{link} if parsed_link then tracked.bad_format = tracked.bad_format or bad_format if links_ns then parsed_label = parsed_label or parsed_link parsed_link = mw.site.namespaces[links_ns].name .. ':' .. parsed_link end local title = mw.title.new(parsed_link) tracked.red_link = tracked.red_link or not (title.isExternal or title.exists) element = p.format_link{parsed_link, nil, label or parsed_label} else tracked.unparsable_link = true element = link end end if bold_links then element = string.format('<b>%s</b>', element) end table.insert(res_list, element) i = i + 1 end return setmetatable(res_list, { __index = tracked, __tostring = function (self) return mw.text.listToText(self, list_sep, last_list_sep) end, __concat = concat, __pairs = function (self) return pairs(tracked) end }) end function p.hatnote(frame) local args = get_args(frame) local text = args[1] local id = args.id local extraclasses = args.extraclasses local hide_disambig = yesno(args.hide_disambig) local res = mw.html.create('div') :attr('id', id) :addClass('hatnote') :addClass('navigation-not-searchable') :addClass(extraclasses) :wikitext(text) if hide_disambig then res:addClass('dabhide') end return res end function p.main(frame, _tracking_categories) local args = get_args(frame, {trim = false}) local prefix = args.prefix or args['префикс'] local prefix_plural = args.prefix_plural or args['префикс мн. ч.'] local sep = args.sep or args['разделитель'] or ' ' local dot = yesno(args.dot or args['точка']) and '.' or '' local nocat = yesno(args.nocat) local preview_error = yesno(args.preview_error) local empty_list_message = args.empty_list_message or 'Не указано ни одной страницы' categories = tr.define_categories(index(_tracking_categories or {}, tracking_categories)) if not prefix then categories:add('no_prefix', nocat) return tr.error('Не указан префикс', categories) end if not args[1] then categories:add('no_links', nocat) return tr.error(empty_list_message, categories, preview_error) end if args[2] and prefix_plural then prefix = prefix_plural end local list = p.list(args) for k, v in pairs(list) do if type(v) == 'boolean' and v then categories:add(k, nocat) end end return p.hatnote(index({prefix .. sep .. list .. dot}, args)) .. categories end return index(p, tr) 315cdda5f53c2b0188793a6cc6c40f7f371361e0 Модуль:Wikidata/media 828 149 340 2021-07-13T21:52:06Z ruwiki>Putnik 0 alt=Логотип Викисклада Scribunto text/plain local p = {} -- Константы local contentLanguageCode = mw.getContentLanguage():getCode(); function p.formatCommonsCategory( context, options, value ) local link = 'commons:Category:' .. value local title = value .. ' на Викискладе' if ( options['text'] and options['text'] ~= '' ) then title = options['text'] end commons = '[[' .. link .. '|' .. title .. ']]' --Commons icon if ( not options['icon'] or options['icon'] ~= '-' ) then local icon_size = '15px' if ( options['icon_size'] and options['icon_size'] ~= '' ) then icon_size = options['icon_size'] end commons = '[[File:Commons-logo.svg|' .. icon_size .. '|link=' .. link .. '|alt=Логотип Викисклада]] ' .. commons end --Text before and after link if ( options['text_before'] and options['text_before'] ~= '' ) then if ( options['text_before'] ~= '-' ) then commons = options['text_before'] .. ' ' .. commons end end if ( options['text_after'] and options['text_after'] ~= '' ) then if ( options['text_after'] ~= '-' ) then commons = commons .. ' ' .. options['text_after'] end end return commons end --[[ Временный хак, нужно добавить config, getConfig и getCategoryByCode в options, чтобы они были доступны в любом месте кода. ]] local config; local function getCategoryByCode( code, sortkey ) if config == nil then config = require( 'Module:Wikidata/config' ); end; local value = config[ 'categories' ][ code ]; if not value or value == '' then return ''; end return '[[Category:' .. value .. ']]'; end local function getCaption( context, options ) local caption = '' if options.qualifiers and options.qualifiers.P2096 then for i, qualifier in pairs( options.qualifiers.P2096 ) do if ( qualifier and qualifier.datavalue and qualifier.datavalue.type == 'monolingualtext' and qualifier.datavalue.value and qualifier.datavalue.value.language == contentLanguageCode ) then caption = qualifier.datavalue.value.text break end end end if options['appendTimestamp'] and options.qualifiers and options.qualifiers.P585 and options.qualifiers.P585[1] then local moment = context.formatValueDefault( context, options, options.qualifiers.P585[1].datavalue ) if not caption or caption == '' then caption = moment else caption = caption .. ', ' .. moment end end local localValue = ''; if options[ 'value' ] and options[ 'value' ] ~= '' then localValue = options[ 'value' ]; end local localCaption = ''; if options[ 'caption' ] and options[ 'caption' ] ~= '' then localCaption = options[ 'caption' ]; end if localValue ~= '' then caption = localCaption; end local formattedCaption = '' if caption ~= '' then formattedCaption = context.wrapQualifier( caption, 'P2096', { class = 'media-caption', style = 'display:block' } ); end if localValue == '' and localCaption ~= '' then formattedCaption = formattedCaption .. getCategoryByCode( 'media-contains-local-caption' ) if options.frame:preprocess('{{REVISIONID}}') == '' then formattedCaption = formattedCaption .. '<span class="error" style="font-size:94%;">Локальная подпись не используется, потому что изображение берётся из Викиданных, см. [[Википедия:Шаблоны-карточки#Описание изображения в Викиданных|здесь]]</span>' end end return caption, formattedCaption end function p.formatCommonsMediaValue( context, options, value ) local image = value; local caption, formattedCaption = getCaption( context, options ) if not string.find( value, '[%[%]%{%}]' ) and not string.find( value, 'UNIQ%-%-imagemap' ) then -- если в value не содержится викикод или imagemap, то викифицируем имя файла -- ищем слово imagemap в строке, потому что вставляется плейсхолдер: [[PHAB:T28213]] image = '[[File:' .. value .. '|frameless'; if options[ 'border' ] and options[ 'border' ] ~= '' then image = image .. '|border'; end local size = options[ 'size' ]; if size and size ~= '' then if not string.match( size, 'px$' ) and not string.match( size, 'пкс$' ) -- TODO: использовать перевод для языка вики then size = size .. 'px' end -- временно if string.match( size, 'pxpx' ) then image = '[[Категория:Википедия:Изображение с pxpx в размере]]' .. image end else size = fileDefaultSize; end image = image .. '|' .. size; if options[ 'alt' ] and options[ 'alt' ] ~= '' then image = image .. '|alt=' .. options[ 'alt' ]; end if caption ~= '' then image = image .. '|' .. caption end image = image .. ']]'; if formattedCaption ~= '' then image = image .. '<br>' .. formattedCaption; end else image = image .. formattedCaption .. getCategoryByCode( 'media-contains-markup' ); end if options.entity and options.fixdouble then local page = mw.title.getCurrentTitle() local txt = page:getContent() if txt and txt:match(':' .. value) and mw.title.getCurrentTitle():inNamespace(0) then if options.frame:preprocess('{{REVISIONID}}') == '' then image = image .. '<span class="error">Это изображение встречается ниже по тексту статьи; пожалуйста, уберите одну из копий (не потеряв при этом подпись)</span>' end image = image .. getCategoryByCode( 'media-contains-local-double' ) end end return image end return p ec384e72491465f4103cce95a8f9467df428a432 Шаблон:Tlinks 10 234 549 2021-07-29T21:07:51Z ruwiki>WerySkok 0 1 версия импортирована: Импорт Инфобокса из Русскоязычной википедии. wikitext text/x-wiki #перенаправление [[Шаблон:Действия для страницы]] 8d69cbc167e009846a8f6ad7cd75b790882aeff5 Шаблон:Tlp 10 217 643 2021-07-29T21:07:55Z ruwiki>WerySkok 0 16 версий импортировано: Импорт Инфобокса из Русскоязычной википедии. wikitext text/x-wiki {{{{{|safesubst:}}}#invoke: Template call code | withParams | _link = 1 }}<noinclude>{{doc}}</noinclude> 36c309cb28ccf0901f4fff46cbd35cdabcf00661 Шаблон:Конец скрытого блока 10 199 649 444 2021-07-29T21:08:08Z ruwiki>WerySkok 0 1 версия импортирована: Импорт Инфобокса из Русскоязычной википедии. wikitext text/x-wiki <includeonly></div></div></includeonly><noinclude> {{doc|Шаблон:Начало скрытого блока/doc}}</noinclude> 2da6ac8eb0812fb4183a70b516009d40920e281f Шаблон:Начало скрытого блока 10 196 651 2021-07-29T21:08:09Z ruwiki>WerySkok 0 1 версия импортирована: Импорт Инфобокса из Русскоязычной википедии. wikitext text/x-wiki <includeonly><!-- --><div class="NavFrame collapsibleBox {{#ifeq: {{{тип|{{{type|}}}}}} | transparent | collapsibleBox-transparent}} {{{состояние|{{{state|collapsed}}}}}}" style="{{#if: {{{Рамка|{{{border|{{{рамка|}}}}}}}}} | border:{{{Рамка|{{{border|{{{рамка}}}}}}}}};}}{{{frame-style|{{{стиль_тела|}}}}}}"><!-- --><div class="NavHead collapsibleBox-title {{#ifeq: {{{Выравнивание_заголовка|{{{ta1|{{{выравнивание_заголовка|}}}}}}}}} | left | collapsibleBox-title-leftTitle | {{#ifeq: {{{Выравнивание_заголовка|{{{ta1|{{{выравнивание_заголовка|}}}}}}}}} | right | collapsibleBox-title-rightTitle}}}} {{#ifeq: {{{Ссылка|{{{ссылка|}}}}}} | left | collapsibleBox-title-leftHideLink | collapsibleBox-title-rightHideLink}}" style="<!-- -->{{#if: {{{Фон_заголовка|{{{bg1|{{{фон_заголовка|}}}}}}}}} | background-color:{{{Фон_заголовка|{{{bg1|{{{фон_заголовка}}}}}}}}};}}<!-- -->{{#if: {{{Выравнивание_заголовка|{{{ta1|{{{выравнивание_заголовка|}}}}}}}}} | text-align:{{{Выравнивание_заголовка|{{{ta1|{{{выравнивание_заголовка}}}}}}}}};}}<!-- -->{{#if: {{{Шрифт_заголовка|{{{шрифт_заголовка|}}}}}} | font-weight:{{{Шрифт_заголовка|{{{шрифт_заголовка}}}}}};}}<!-- -->{{#if: {{{Наклон_заголовка|{{{наклон_заголовка|}}}}}} | font-style:{{{Наклон_заголовка|{{{наклон_заголовка}}}}}};}}<!-- -->{{{Стиль_заголовка|{{{extra1|{{{стиль_заголовка|}}}}}}}}}"><!-- -->{{{Заголовок|{{{заголовок|{{{Заглавие|{{{заглавие|{{{Название|{{{название|{{{header|{{{title|{{{1}}}}}}}}}}}}}}}}}}}}}}}}}}}</div><!-- --><div class="NavContent" style="<!-- -->{{#if: {{{Фон_текста|{{{bg2|{{{фон_текста|}}}}}}}}} | background-color:{{{Фон_текста|{{{bg2|{{{фон_текста}}}}}}}}};}}<!-- -->{{#if: {{{Шрифт_текста|{{{шрифт_текста|}}}}}} | font-weight:{{{Шрифт_текста|{{{шрифт_текста}}}}}};}}<!-- -->{{#if: {{{Наклон_текста|{{{наклон_текста|}}}}}} | font-style:{{{Наклон_текста|{{{наклон_текста}}}}}};}}<!-- -->{{#if: {{{Выравнивание_текста|{{{ta2|{{{выравнивание_текста|}}}}}}}}} | text-align:{{{Выравнивание_текста|{{{ta2|{{{выравнивание_текста}}}}}}}}};}}<!-- -->{{{Стиль_текста|{{{extra2|{{{стиль_текста|}}}}}}}}}"><!-- --></includeonly><noinclude>{{doc}}</noinclude> 9de884ce18dcea913832ac31c70e5ddaa0d0d775 Шаблон:Скрытый 10 203 653 452 2021-07-29T21:08:11Z ruwiki>WerySkok 0 1 версия импортирована: Импорт Инфобокса из Русскоязычной википедии. wikitext text/x-wiki #перенаправление [[Шаблон:Скрытый блок]] 97cc939c1c8ece875b2ec360f85980bd6f1bbed7 Шаблон:Скрытый блок 10 200 655 2021-07-29T21:08:12Z ruwiki>WerySkok 0 1 версия импортирована: Импорт Инфобокса из Русскоязычной википедии. wikitext text/x-wiki {{Начало скрытого блока |тип = {{{тип|{{{type|}}}}}} |состояние = {{{state|{{{состояние|collapsed}}}}}} |стиль_тела = {{{frame-style|{{{стиль_тела|}}}}}} |рамка = {{{Рамка|{{{border|{{{рамка|}}}}}}}}} |заголовок = {{{Заголовок|{{{заголовок|{{{Заглавие|{{{заглавие|{{{Название|{{{название|{{{header|{{{title|{{{1}}}}}}}}}}}}}}}}}}}}}}}}}}} |ссылка = {{{Ссылка|{{{ссылка|}}}}}} |шрифт_заголовка = {{{Шрифт_заголовка|{{{шрифт_заголовка|}}}}}} |наклон_заголовка = {{{Наклон_заголовка|{{{наклон_заголовка|}}}}}} |фон_заголовка = {{{Фон_заголовка|{{{bg1|{{{фон_заголовка|}}}}}}}}} |выравнивание_заголовка = {{{Выравнивание_заголовка|{{{ta1|{{{выравнивание_заголовка|}}}}}}}}} |стиль_заголовка = {{{title-style|{{{Стиль_заголовка|{{{extra1|{{{стиль_заголовка|}}}}}}}}}}}} |шрифт_текста = {{{Шрифт_текста|{{{шрифт_текста|}}}}}} |наклон_текста = {{{Наклон_текста|{{{наклон_текста|}}}}}} |фон_текста = {{{Фон_текста|{{{bg2|{{{фон_текста|}}}}}}}}} |выравнивание_текста = {{{Выравнивание_текста|{{{ta2|{{{выравнивание_текста|}}}}}}}}} |стиль_текста = {{{content-style|{{{Стиль_текста|{{{extra2|{{{стиль_текста|}}}}}}}}}}}}}} {{{content|{{{Содержание|{{{содержание|{{{2}}}}}}}}}}}} {{#if: {{{footer|}}} | <div style="{{{footer-style|{{{title-style|}}}}}}">{{{footer}}}</div> }} {{Конец скрытого блока}}<noinclude>{{doc}}</noinclude> a45c5c78c8132fc840a5e2e10364c35f2cdf5dcc Модуль:Arguments 828 124 563 290 2021-07-29T21:08:13Z ruwiki>WerySkok 0 1 версия импортирована: Импорт Инфобокса из Русскоязычной википедии. Scribunto text/plain -- This module provides easy processing of arguments passed to Scribunto from -- #invoke. It is intended for use by other Lua modules, and should not be -- called from #invoke directly. local libraryUtil = require('libraryUtil') local checkType = libraryUtil.checkType local arguments = {} -- Generate four different tidyVal functions, so that we don't have to check the -- options every time we call it. local function tidyValDefault(key, val) if type(val) == 'string' then val = val:match('^%s*(.-)%s*$') if val == '' then return nil else return val end else return val end end local function tidyValTrimOnly(key, val) if type(val) == 'string' then return val:match('^%s*(.-)%s*$') else return val end end local function tidyValRemoveBlanksOnly(key, val) if type(val) == 'string' then if val:find('%S') then return val else return nil end else return val end end local function tidyValNoChange(key, val) return val end local function matchesTitle(given, title) local tp = type( given ) return (tp == 'string' or tp == 'number') and mw.title.new( given ).prefixedText == title end local translate_mt = { __index = function(t, k) return k end } function arguments.getArgs(frame, options) checkType('getArgs', 1, frame, 'table', true) checkType('getArgs', 2, options, 'table', true) frame = frame or {} options = options or {} --[[ -- Set up argument translation. --]] options.translate = options.translate or {} if getmetatable(options.translate) == nil then setmetatable(options.translate, translate_mt) end if options.backtranslate == nil then options.backtranslate = {} for k,v in pairs(options.translate) do options.backtranslate[v] = k end end if options.backtranslate and getmetatable(options.backtranslate) == nil then setmetatable(options.backtranslate, { __index = function(t, k) if options.translate[k] ~= k then return nil else return k end end }) end --[[ -- Get the argument tables. If we were passed a valid frame object, get the -- frame arguments (fargs) and the parent frame arguments (pargs), depending -- on the options set and on the parent frame's availability. If we weren't -- passed a valid frame object, we are being called from another Lua module -- or from the debug console, so assume that we were passed a table of args -- directly, and assign it to a new variable (luaArgs). --]] local fargs, pargs, luaArgs if type(frame.args) == 'table' and type(frame.getParent) == 'function' then if options.wrappers then --[[ -- The wrappers option makes Module:Arguments look up arguments in -- either the frame argument table or the parent argument table, but -- not both. This means that users can use either the #invoke syntax -- or a wrapper template without the loss of performance associated -- with looking arguments up in both the frame and the parent frame. -- Module:Arguments will look up arguments in the parent frame -- if it finds the parent frame's title in options.wrapper; -- otherwise it will look up arguments in the frame object passed -- to getArgs. --]] local parent = frame:getParent() if not parent then fargs = frame.args else local title = parent:getTitle():gsub('/песочница$', '') local found = false if matchesTitle(options.wrappers, title) then found = true elseif type(options.wrappers) == 'table' then for _,v in pairs(options.wrappers) do if matchesTitle(v, title) then found = true break end end end -- We test for false specifically here so that nil (the default) acts like true. if found or options.frameOnly == false then pargs = parent.args end if not found or options.parentOnly == false then fargs = frame.args end end else -- options.wrapper isn't set, so check the other options. if not options.parentOnly then fargs = frame.args end if not options.frameOnly then local parent = frame:getParent() pargs = parent and parent.args or nil end end if options.parentFirst then fargs, pargs = pargs, fargs end else luaArgs = frame end -- Set the order of precedence of the argument tables. If the variables are -- nil, nothing will be added to the table, which is how we avoid clashes -- between the frame/parent args and the Lua args. local argTables = {fargs} argTables[#argTables + 1] = pargs argTables[#argTables + 1] = luaArgs --[[ -- Generate the tidyVal function. If it has been specified by the user, we -- use that; if not, we choose one of four functions depending on the -- options chosen. This is so that we don't have to call the options table -- every time the function is called. --]] local tidyVal = options.valueFunc if tidyVal then if type(tidyVal) ~= 'function' then error( "bad value assigned to option 'valueFunc'" .. '(function expected, got ' .. type(tidyVal) .. ')', 2 ) end elseif options.trim ~= false then if options.removeBlanks ~= false then tidyVal = tidyValDefault else tidyVal = tidyValTrimOnly end else if options.removeBlanks ~= false then tidyVal = tidyValRemoveBlanksOnly else tidyVal = tidyValNoChange end end --[[ -- Set up the args, metaArgs and nilArgs tables. args will be the one -- accessed from functions, and metaArgs will hold the actual arguments. Nil -- arguments are memoized in nilArgs, and the metatable connects all of them -- together. --]] local args, metaArgs, nilArgs, metatable = {}, {}, {}, {} setmetatable(args, metatable) local function mergeArgs(tables) --[[ -- Accepts multiple tables as input and merges their keys and values -- into one table. If a value is already present it is not overwritten; -- tables listed earlier have precedence. We are also memoizing nil -- values, which can be overwritten if they are 's' (soft). --]] for _, t in ipairs(tables) do for key, val in pairs(t) do if metaArgs[key] == nil and nilArgs[key] ~= 'h' then local tidiedVal = tidyVal(key, val) if tidiedVal == nil then nilArgs[key] = 's' else metaArgs[key] = tidiedVal end end end end end --[[ -- Define metatable behaviour. Arguments are memoized in the metaArgs table, -- and are only fetched from the argument tables once. Fetching arguments -- from the argument tables is the most resource-intensive step in this -- module, so we try and avoid it where possible. For this reason, nil -- arguments are also memoized, in the nilArgs table. Also, we keep a record -- in the metatable of when pairs and ipairs have been called, so we do not -- run pairs and ipairs on the argument tables more than once. We also do -- not run ipairs on fargs and pargs if pairs has already been run, as all -- the arguments will already have been copied over. --]] metatable.__index = function (t, key) --[[ -- Fetches an argument when the args table is indexed. First we check -- to see if the value is memoized, and if not we try and fetch it from -- the argument tables. When we check memoization, we need to check -- metaArgs before nilArgs, as both can be non-nil at the same time. -- If the argument is not present in metaArgs, we also check whether -- pairs has been run yet. If pairs has already been run, we return nil. -- This is because all the arguments will have already been copied into -- metaArgs by the mergeArgs function, meaning that any other arguments -- must be nil. --]] if type(key) == 'string' then key = options.translate[key] end local val = metaArgs[key] if val ~= nil then return val elseif metatable.donePairs or nilArgs[key] then return nil end for _, argTable in ipairs(argTables) do local argTableVal = tidyVal(key, argTable[key]) if argTableVal ~= nil then metaArgs[key] = argTableVal return argTableVal end end nilArgs[key] = 'h' return nil end metatable.__newindex = function (t, key, val) -- This function is called when a module tries to add a new value to the -- args table, or tries to change an existing value. if type(key) == 'string' then key = options.translate[key] end if options.readOnly then error( 'could not write to argument table key "' .. tostring(key) .. '"; the table is read-only', 2 ) elseif options.noOverwrite and args[key] ~= nil then error( 'could not write to argument table key "' .. tostring(key) .. '"; overwriting existing arguments is not permitted', 2 ) elseif val == nil then --[[ -- If the argument is to be overwritten with nil, we need to erase -- the value in metaArgs, so that __index, __pairs and __ipairs do -- not use a previous existing value, if present; and we also need -- to memoize the nil in nilArgs, so that the value isn't looked -- up in the argument tables if it is accessed again. --]] metaArgs[key] = nil nilArgs[key] = 'h' else metaArgs[key] = val end end local function translatenext(invariant) local k, v = next(invariant.t, invariant.k) invariant.k = k if k == nil then return nil elseif type(k) ~= 'string' or not options.backtranslate then return k, v else local backtranslate = options.backtranslate[k] if backtranslate == nil then -- Skip this one. This is a tail call, so this won't cause stack overflow return translatenext(invariant) else return backtranslate, v end end end metatable.__pairs = function () -- Called when pairs is run on the args table. if not metatable.donePairs then mergeArgs(argTables) metatable.donePairs = true end return translatenext, { t = metaArgs } end local function inext(t, i) -- This uses our __index metamethod local v = t[i + 1] if v ~= nil then return i + 1, v end end metatable.__ipairs = function (t) -- Called when ipairs is run on the args table. return inext, t, 0 end return args end return arguments e6be8dfccffa2057c3d50700f350d8d140c1dbf9 Модуль:Calendar 828 62 611 2021-07-29T21:08:14Z ruwiki>WerySkok 0 1 версия импортирована: Импорт Инфобокса из Русскоязычной википедии. Scribunto text/plain local p = {} -- Необходимые модули и переменные local getArgs = require('Module:Arguments').getArgs local yesno = require('Module:Yesno') local mwlang = mw.getContentLanguage() local err = "―" -- NthDay nil result local tCon = table.concat -- 00) Блок многократно используемых списков local bool_to_number={ [true]=1, [false]=0 } local monthlang = {"января","февраля","марта","апреля","мая","июня","июля","августа","сентября","октября","ноября","декабря"} local month_to_num = {["января"]=1,["февраля"]=2,["марта"]=3,["апреля"]=4,["мая"]=5,["июня"]=6, ["июля"]=7,["августа"]=8,["сентября"]=9,["октября"]=10,["ноября"]=11,["декабря"]=12,["-"]=""} local monthd = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} local params = { {"г", "g"}, {"ю", "j"}} local comment = { '<span style="border-bottom: 1px dotted; cursor: help" title="по юлианскому календарю">','</span>'} -- duplicates: -- AST, BST, CST, ECT, IST, MST, PST, SST, local known_tzs = { ACDT='+10:30', ACST='+09:30', ACT ='+08:00', ADT ='-03:00', AEDT ='+11:00', AEST='+10:00', AFT ='+04:30', AKDT='-08:00', AKST ='-09:00', AMST ='+05:00', AMT ='+04:00', ART ='-03:00', AST ='+03:00', AST ='+04:00', AST ='+03:00', AST ='-04:00', AWDT='+09:00', AWST='+08:00', AZOST='-01:00', AZT ='+04:00', BDT ='+08:00', BIOT='+06:00', BIT ='-12:00', BOT ='-04:00', BRT ='-03:00', BST ='+06:00', BST ='+01:00', BTT ='+06:00', CAT ='+02:00', CCT ='+06:30', CDT ='-05:00', CEDT='+02:00', CEST='+02:00', CET ='+01:00', CHAST='+12:45', CIST='-08:00', CKT ='-10:00', CLST='-03:00', CLT ='-04:00', COST ='-04:00', COT ='-05:00', CST ='-06:00', CST ='+08:00', CVT ='-01:00', CXT ='+07:00', CHST='+10:00', DFT ='+01:00', EAST='-06:00', EAT ='+03:00', ECT ='-04:00', ECT ='-05:00', EDT ='-04:00', EEDT='+03:00', EEST ='+03:00', EET ='+02:00', EST ='-05:00', FJT ='+12:00', FKST='-03:00', FKT ='-04:00', GALT ='-06:00', GET ='+04:00', GFT ='-03:00', GILT='+12:00', GIT ='-09:00', GMT ='+00:00', GST ='-02:00', GYT ='-04:00', HADT='-09:00', HAST ='-10:00', HKT ='+08:00', HMT ='+05:00', HST ='-10:00', IRKT='+08:00', IRST ='+03:30', IST ='+05:30', IST ='+01:00', IST ='+02:00', JST ='+09:00', KRAT ='+07:00', KST ='+09:00', LHST='+10:30', LINT='+14:00', MAGT='+11:00', MDT ='-06:00', MIT ='-09:30', MSD ='+04:00', MSK ='+03:00', MST ='+08:00', MST ='-07:00', MST ='+06:30', MUT ='+04:00', NDT ='-02:30', NFT ='+11:30', NPT ='+05:45', NST ='-03:30', NT ='-03:30', OMST='+06:00', PDT ='-07:00', PETT ='+12:00', PHOT ='+13:00', PKT ='+05:00', PST ='-08:00', PST ='+08:00', RET ='+04:00', SAMT ='+04:00', SAST='+02:00', SBT ='+11:00', SCT ='+04:00', SLT ='+05:30', SST ='-11:00', SST ='+08:00', TAHT='-10:00', THA ='+07:00', UTC ='+00:00', UYST ='-02:00', UYT ='-03:00', VET ='-04:30', VLAT='+10:00', WAT ='+01:00', WEDT ='+01:00', WEST='+01:00', WET ='+00:00', YAKT='+09:00', YEKT ='+05:00', -- US Millitary (for RFC-822) Z='+00:00', A='-01:00', M='-12:00', N='+01:00', Y='+12:00', } local category = { ["no_parameters"]= "<!--[[Категория:Модуль:Calendar:Страницы без параметров]]-->", ["incomplete_parameters"]= "<!--[[Категория:Модуль:Calendar:Страницы с неполными или некорректными параметрами]]-->", ["without_verification"]= "<!--[[Категория:Модуль:Calendar:Страницы без проверки параметров]]-->", ["erroneous_parameters"]= "<!--[[Категория:Модуль:Calendar:Страницы с ошибочными параметрами]]-->" } -- несколько параметров передаются вместе с кодом ошибки в таблице, один может быть передан простым значением local e = { ["start"]="<span class=error>Ошибка: ", ["ending"]=".</span>", ["no_pattern_match"]="строка «%s» не совпадает с заданными паттернами", ["no_valid_date"]="дата «%s» не является корректной", ["wrong_jd"]="юлианская дата %s вне диапазона", ["no_data"]="нет входящих данных", ["too_many_arguments"]="ожидается менее %i аргументов", ["too_little_arguments"]="ожидается более %i аргументов", ["wrong_calculation"]="даты %s и %s не прошли проверку, %s дней разница", ["unknown_param"]="параметр %s неизвестен", ["unknown_error"]="неизвестная ошибка", ["tech_error"]="ошибка в функции %s", ["box_date"]="строка «%s» не является верной датой, пожалуйста, укажите дату в формате ГГГГ-ММ-ДД" -- [""]="", } local tzs_names = {"ACDT","ACST","ACT","ADT","AEDT","AEST","AFT","AKDT","AKST", "AMST","AMT","ART","AST","AST","AST","AST","AWDT","AWST","AZOST","AZT","BDT", "BIOT","BIT","BOT","BRT","BST","BST","BTT","CAT","CCT","CDT","CEDT","CEST", "CET","CHAST","CIST","CKT","CLST","CLT","COST","COT","CST","CST","CVT","CXT", "CHST","DFT","EAST","EAT","ECT","ECT","EDT","EEDT","EEST","EET","EST","FJT", "FKST","FKT","GALT","GET","GFT","GILT","GIT","GMT","GST","GYT","HADT","HAST", "HKT","HMT","HST","IRKT","IRST","IST","IST","IST","JST","KRAT","KST","LHST", "LINT","MAGT","MDT","MIT","MSD","MSK","MST","MST","MST","MUT","NDT","NFT", "NPT","NST","NT","OMST","PDT","PETT","PHOT","PKT","PST","PST","RET","SAMT", "SAST","SBT","SCT","SLT","SST","SST","TAHT","THA","UTC","UYST","UYT","VET", "VLAT","WAT","WEDT","WEST","WET","YAKT","YEKT","Z","A","M","N","Y","MSK"} local pattern = { -- для распознавания дат, переданных одним строчным параметром {"(-?%d%d%d%d?)[-%.%s/\\](%d%d)[-%.%s/\\](%d%d)", ["order"] = {3,2,1} }, -- yyyy mm dd {"(%d+)[-%.%s/\\](%d+)[-%.%s/\\](%d%d%d%d?)", ["order"] = {1,2,3} }, -- dd mm yyyy {"(%d%d)[-%.%s/\\](%d%d%d%d?)", ["order"] = {2,3} }, -- mm yyyy {"(%d%d%d%d?)[-%.%s/\\](%d%d)", ["order"] = {3,2} }, -- yyyy mm {"(%d+)%s(%l+)%s(%d%d%d%d?)", ["order"] = {1,2,3} }, -- d mmm y {"(%l+)%s(%d+),?%s(%d%d%d%d?)", ["order"] = {2,1,3} }, -- mmm d, y {"(%l+)%s(%d%d%d%d?)", ["order"] = {2,3} }, -- mmm y } local time_units = {"year","month","day"} --не используется --[[ local time_units = {"second", "minute", "hour", "day_of_month", "day_of_week", "day_of_year", "week", "month", "year", "year_of_century", "century"} ]]-- -- напоминание чтобы сделать более точные пересчёты - с часами / расчёт длительностей периодов local mnlang = {"ru_G", "ru_N", "en", "de", "fr"} local month_lang = { ["ru_G"] = {"января","февраля","марта","апреля","мая","июня", "июля","августа","сентября","октября","ноября","декабря"}, ["ru_N"] = {"январь","февраль","март","апрель","май","июнь", "июль","август","сентябрь","октябрь","ноябрь","декабрь"}, ["en"] = {"january", "february", "march", "april", "may", "june", "july", "august", "september", "october", "november", "december"}, ["de"] = {"januar", "februar", "märz", "april", "mai", "juni", "juli", "august", "september", "oktober", "november", "dezember"}, ["fr"] = {"janvier", "février", "mars", "avril", "mai", "juin", "juillet", "août", "septembre", "octobre", "novembre", "décembre"} } -- заполняется автоматически local reverse_month_lang = {} -- вспомогательная функция для обращения таблиц (смена ключей со значениями) local reverse_table = function (strait_table) local reversed_table = {} for k,v in pairs(strait_table) do reversed_table[v] = k end return reversed_table end -- запуск цикла по заполнению обратных таблиц, необходимых для распознавания дат local filling_months = function (mnlang, month_lang) for i=1, #mnlang do reverse_month_lang[mnlang[i]] = reverse_table(month_lang[mnlang[i]]) end end -- 10) Блок общих функций local function trim(str) if not str then return nil else return str:match'^()%s*$' and '' or str:match'^%s*(.*%S)' end end local function purif(str) if str == "" or str == nil then return nil elseif type(tonumber(str)) == "number" then return math.floor(tonumber(str)) else return nil end -- need .5 -- ,5 number format converter? end local function is(str) if (not str) or (str == "") then return false else return yesno(str,false) end end local function init(num) local output = {} for i=1,num do table.insert(output, {["year"]="", ["month"]="", ["day"]=""}) end return unpack(output) end local function isyear(tbl) if type(tbl) ~= 'table' then return false elseif not tbl["year"] then return false elseif type(tbl["year"]) == 'number' then return true else return false end end local function inbord(val, down, up) return not (type(up) ~= "number" or type(down) ~= "number" or type(val) ~= "number" or up < down or val < down or val > up) end local function shallowcopy(orig) local orig_type = type(orig) local copy if orig_type == 'table' then copy = {} for orig_key, orig_value in pairs(orig) do copy[orig_key] = orig_value end else -- number, string, boolean, etc copy = orig end return copy end local inlist = function ( var, list ) local n = #list local inlist = false for i=1,n do if var == list[i] then inlist = true end end return inlist end -- 20) Блок общих проверочных функций, связанных с датами local function unwarp(tbl) if not tbl then return "" elseif type(tbl) ~= "table" then return tbl elseif (tbl.day or tbl.month or tbl.year) then return (tbl.year or "?").."-"..(tbl.month or "?").."-"..(tbl.day or "?") else return (tbl[3] or "?").."-"..(tbl[2] or "?").."-"..(tbl[1] or "?") end end local function leap_year(y,jul) if (not y) or (type(y) ~= "number") then return false elseif (y % 4) ~= 0 then return false elseif not jul and (y % 100 == 0 and y % 400 ~= 0) then return false else return true end end -- функция для вычисления последнего дня месяца для юлианского и григорианского календарей local function month_end_day (month,year,is_julian) local month_end_day = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} -- если не задан год, дата 29 февраля считается допустимой if not month or type(month) ~= "number" or month < 1 or month > 12 then return nil elseif month ~= 2 or not year then return month_end_day[month] elseif month == 2 and (year % 4) == 0 and not ((not is_julian) and (year % 100 == 0 and year % 400 ~= 0)) then return 29 elseif month == 2 then return 28 else return nil -- в случае не целого значения входящих параметров или при иных непредусмотренных событиях end end local function isdate ( chain , jul ) -- можно использовать для проверки таблиц с полями day, month, year if not chain then return false elseif (not type(chain) == "table") or (not inbord(chain.year,-9999,9999)) or (not inbord(chain.month,1,12)) or (not inbord(chain.day,1,31)) or chain.day > monthd[chain.month] -- or chain.year == 0 then return false elseif chain.month == 2 and chain.day == 29 and not leap_year(chain.year,jul) then return false else return true end -- check for other calendars needed? end local function ispartdate ( chain ) if not chain then return false elseif not (type(chain) == "table") then return false elseif (inbord(chain.year,-9999,9999) or inbord(chain.month,1,12) or inbord(chain.day,1,31)) then return true else return false end -- partial date -- more detailed check for 31.02.0000 needed -- check for other calendars needed end -- from date1 to date2 in one year (beetwen jan-dec, dec-jan needed) local function partdist(date1,date2) local mont, dist = 0, 0 local d1d, d1m, d2d, d2m = (date1["day"] or ""), (date1["month"] or ""),(date2["day"] or ""), (date2["month"] or "") if not (inbord(d1d,1,31) and inbord(d2d,1,31)) then return false end -- нужна доп. проверка частичных дат на корректность if (inbord(d1m,1,12) or inbord(d2m,1,12)) and (d1m == "" or d2m == "") then mont = purif(date1["month"] or date2["month"]) d1m, d2m = mont, mont end -- mw.log("📏 day: " ..d1d .."->"..d2d.." month: ".. d1m.."->"..d2m ) if (inbord(d1m,1,12) and d1d <= monthd[d1m]) and (inbord(d2m,1,12) and d2d <= monthd[d2m]) then if d2m == d1m then dist = d2d - d1d else dist = monthd[d1m] - d1d + d2d end return dist else return math.huge end end local function dmdist(d1,d2) local p1,p2 = math.huge,math.huge if not not partdist(d1,d2) then p1=partdist(d1,d2) end if not not partdist(d2,d1) then p1=partdist(d2,d1) end -- if (not p1) or (not p2) then -- return (p1 or "") .. (p2 or "") -- else -- mw.log("d1, d2 = " .. undate(d1) .. ", " .. undate(d2)) return math.min(tonumber(partdist(d1,d2)) or math.huge,tonumber(partdist(d2,d1)) or math.huge) -- end end -- 30) Блок функций для обработки ввода-вывода дат local function undate(tbl) if not tbl then return "" else return (tbl.year or "").."-"..(tbl.month or "").."-"..(tbl.day or "") end end -- функция для нормализации значений дат и перевода месяцев в числа local function numerize(str) if type(str) == "number" then return math.floor(str) elseif str == "" or str == nil or type(str) ~= "string" then return nil elseif type(tonumber(str)) == "number" then return math.floor(tonumber(str)) else for i=1, #mnlang do if inlist(mw.ustring.lower(str),month_lang[mnlang[i]]) then return reverse_month_lang[mnlang[i]][mw.ustring.lower(str)] end end end end -- функция распознавания даты, переданной одной строкой local function parse_date(date_string) if type(date_string) ~= "string" or date_string == "" then return nil end local out_date_str = {"","",""} local error_data = {} for i=1, #pattern do local result_1, result_2, result_3 = mw.ustring.match(mw.ustring.lower(date_string),pattern[i][1]) if (result_1 or "") > "" then out_date_str[pattern[i].order[1]] = result_1 out_date_str[pattern[i].order[2]] = result_2 if (pattern[i].order[3]) then out_date_str[pattern[i].order[3]] = result_3 end -- mw.log("Паттерн " .. i .. ", строка: " .. date_string) break end end local date = { ["day"] =numerize(out_date_str[1]), ["month"]=numerize(out_date_str[2]), ["year"] =numerize(out_date_str[3])} return date --, error_data end ----[[ УСТАРЕЛО ]]---- local numstr2date = function(numstr) local format = "Y-m-d" local iso_date = mwlang:formatDate(format,numstr) local y,m,d = string.match(iso_date, "(%d+)-(%d+)-(%d+)") local dateout = {["year"]=purif(y), ["month"]=purif(m), ["day"]=purif(d)} return dateout end --local numstr2date = function(numstr) -- local nums = {} -- local dateout = {} -- for num in string.gmatch(numstr,"(%d+)") do -- table.insert(nums,purif(num)) -- end -- if #nums ~= 3 then error("В поле даты вместо трёх чисел с разделителями указано " .. #nums) -- elseif not inbord(nums[2],1,12) then error("Месяц с номером " .. nums[2] .. " не найден") -- elseif not inbord(nums[3],1,31) then -- dateout = {["year"]=nums[3], ["month"]=nums[2], ["day"]=nums[1]} -- elseif not inbord(nums[1],1,31) then -- dateout = {["year"]=nums[1], ["month"]=nums[2], ["day"]=nums[3]} -- elseif inbord(nums[1],1,31) then -- dateout = {["year"]=nums[3], ["month"]=nums[2], ["day"]=nums[1]} -- else -- local mwlang = mw.getContentLanguage() -- implement mwlang:formatDate(format,datein,true) here -- return error("Не распознано " .. numstr .. " как дата") -- end -- return dateout --end local function year2lang(numyear,yearmark,wiki) if not numyear then return "" end if not yearmark then yearmark = "" end local output = "" local bcmark = " до н. э." if numyear > 0 then bcmark = "" else numyear = 1 - numyear end if wiki then -- output = tCon({'[[', numyear,' год',bcmark,'|', numyear,']]', " ", yearmark, " ", bcmark}) output = tCon({'[[', numyear,' год',bcmark,'|', trim(numyear .. " " .. yearmark .. " " .. bcmark), ']]'}) else output = tCon({numyear, " ", yearmark, bcmark}) end return trim(output) end local function day2lang(datein,wikidate,wiki,inner_brt) -- if not isdate(wikidate) then wiki = false end if not ispartdate(datein) then return "" end local dm_separ, output = "", nil if (not (not datein.day)) and (not (not datein.month)) then dm_separ = " " end if (not datein.month) then datein.month = "" end if (not datein.day) then datein.day = "" end local monlan = monthlang[datein.month] or "" if wiki and not inner_brt then output = tCon({"[[", wikidate.day, " ", monthlang[wikidate.month] or "", "|", (datein.day or ""), dm_separ, monlan, "]]"}) elseif wiki then output = tCon({"[[", wikidate.day, " ", monthlang[wikidate.month] or "", "|", (datein.day or ""), dm_separ, monlan}) else output = tCon({datein.day, dm_separ, monlan}) end return trim(output) end local function triple_txt2date(d,m,y) -- добавить (args[1]:match("(%a+)") or "-") для нестандартной записи -- mw.ustring.match((m or ""),"(%a+)") local msg = "" local year = purif((y or "-"):match("(%d+)")) local month = purif(month_to_num[string.lower(mw.ustring.match((m or ""),"(%a+)"))]) local day = purif((d or "-"):match("(%d+)")) if not month then msg = category.incomplete_parameters month = purif(month_to_num[string.lower(mw.ustring.match((d or ""),"(%a+)") or "-")]) end if (not day) and ((purif(string.match(m or "","(%d+)") or "") or 32) <= (monthd[month] or 31)) then msg = category.incomplete_parameters day = purif(m:match("(%d+)") or "") end if not year then msg = category.incomplete_parameters year = purif(string.match(m or "","(%d+)") or "") end local dateout = {["year"]=year, ["month"]=month, ["day"]=day, ["msg"]=msg} return dateout end local function glue(d1,m1,y1,d2,m2,y2) if (not d1) and (not m1) and (not y1) and (not d2) and (not m2) and (not y2) then return category.incomplete_parameters end local gd,gm,gy,jd,jm,jy = (d1 or ""), (m1 or ""), (y1 or ""), (d2 or ""), (m2 or ""), (y2 or "") --mw.log(tCon({gd,gm,gy,jd,jm,jy})) local gm_sep = {" [["," год|","]]"} if (not gy) or (gy == "") then gm_sep = {"","",""} end return tCon({comment[1],trim(trim(jd .. " " .. jm) .. " " .. jy ), comment[2]," ([[",trim(gd .. " " .. gm),"]]",gm_sep[1],(gy:match("(%d+)") or ""), gm_sep[2],gy,gm_sep[3],")",category.incomplete_parameters}) end -- добавить отображение без года local function double_couple(jdate, gdate, wd, wm, wy, sq_brts, yearmark) local msg = "" msg = (jdate.msg or "") .. (gdate.msg or "") local cd = {} local jd = shallowcopy(jdate) local gd = shallowcopy(gdate) local left = "(" local right = ")" if sq_brts then left = "&#091;" right = "&#093;" end if (not isdate(jdate,true)) then return error((jdate.day or "") .. "." .. (jdate.month or "") .."." .. (jdate.year or "") .. " неподходящая дата") elseif (not isdate(gdate)) then return error((gdate.day or "") .. "." .. (gdate.month or "") .."." .. (gdate.year or "") .. " неподходящая дата") end if jd.year == gd.year then cd.year = gd.year gd.year, jd.year = nil, nil end if jd.month == gd.month then cd.month = gd.month gd.month, jd.month = nil, nil end if (not not cd.month) and wm then return tCon({comment[1] .. trim(day2lang(jd,jdate,false) .. " " .. year2lang(jd.year,yearmark,false)) .. comment[2], trim(left .. day2lang(gd,gdate,wd,wm) .. " " .. year2lang(gd.year,yearmark,wy)) .. right, day2lang(cd,gdate,false) .. "]]", trim(year2lang(cd.year,yearmark,wy)..msg)}, " ") end return tCon({comment[1] .. trim(day2lang(jd,jdate,false) .. " " .. year2lang(jd.year,yearmark,false)) .. comment[2], trim(left .. day2lang(gd,gdate,wd) .. " " .. year2lang(gd.year,yearmark,wy)) .. right, trim(day2lang(cd,gdate,false)), trim(year2lang(cd.year,yearmark,wy)..msg)}, " ") end -- 40) Блок функций для перевода дат с использованием [[Юлианская дата]] local function gri2jd( datein ) if not isdate(datein) then return error((datein.day or "") .. "." .. (datein.month or "") .."." .. (datein.year or "") .. " неподходящая дата") end local year = datein.year local month = datein.month local day = datein.day -- jd calculation local a = math.floor((14 - month)/12) local y = year + 4800 - a local m = month + 12*a - 3 local offset = math.floor(y/4) - math.floor(y/100) + math.floor(y/400) - 32045 local jd = day + math.floor((153*m + 2)/5) + 365*y + offset -- jd validation local low, high = -1931076.5, 5373557.49999 if not (low <= jd and jd <= high) then return error((datein.day or "") .. "." .. (datein.month or "") .. "." .. (datein.year or "") .. " выходит за пределы разрешённого диапазона") end return jd end local function jd2jul( jd ) if type(jd) ~= "number" then return error("Промежуточная переменная " .. (jd or "") .. " не является числом") end -- calendar date calculation local c = jd + 32082 local d = math.floor((4*c + 3)/1461) local e = c - math.floor(1461*d/4) local m = math.floor((5*e + 2)/153) local year_out = d - 4800 + math.floor(m/10) local month_out = m + 3 - 12*math.floor(m/10) local day_out = e - math.floor((153*m + 2)/5) + 1 -- output local dateout = {["year"]=year_out, ["month"]=month_out, ["day"]=day_out} return dateout end local function jul2jd( datein ) if not isdate(datein,true) then return error((datein.day or "") .. "." .. (datein.month or "") ..".".. (datein.year or "") .. " неподходящая дата") end local year = datein.year local month = datein.month local day = datein.day -- jd calculation local a = math.floor((14 - month)/12) local y = year + 4800 - a local m = month + 12*a - 3 local offset = math.floor(y/4) - 32083 local jd = day + math.floor((153*m + 2)/5) + 365*y + offset -- jd validation local low, high = -1930999.5, 5373484.49999 if not (low <= jd and jd <= high) then return error((datein.day or "") .. "." .. (datein.month or "") .."." .. (datein.year or "") .. " выходит за пределы разрешённого диапазона") end return jd end local function jd2gri( jd ) if type(jd) ~= "number" then return error("Промежуточная переменная " .. (jd or "") .. " не является числом") end -- calendar date calculation local a = jd + 32044 local b = math.floor((4*a + 3) / 146097) local c = a - math.floor(146097*b/4) local d = math.floor((4*c+3)/1461) local e = c - math.floor(1461*d/4) local m = math.floor((5*e+2)/153) local day_out = e - math.floor((153*m+2)/5)+1 local month_out = m + 3 - 12*math.floor(m/10) local year_out = 100*b + d - 4800 + math.floor(m/10) -- output local dateout = {["year"]=year_out, ["month"]=month_out, ["day"]=day_out} return dateout end local function astroyear(num, bc) if not num then return error() elseif type(num) ~= "number" then return error() end if num < 1 then return num end if not bc then return num else return 1 - num end end local function recalc(datein,calend) if inlist(calend,params[1]) then return jd2jul(gri2jd(datein)), datein elseif inlist(calend,params[2]) then return datein, jd2gri(jul2jd(datein)) else error("Параметр " .. (calend or "") .. " не опознан, разрешённые: " .. tCon(params[1]," ") .. " и " .. tCon(params[2]," ")) end end -- 50) Функции для обработки UTC local function utc(str,margin) local d = 1 local dchar = "+" local beginning = "[[UTC" local ending = "]]" local cat = "" local nums = {} local hmarg, timedec = 0, 0 local mmarg = "00" local output = "" -- checking type of input if not margin then margin = 0 elseif type(tonumber(margin)) ~= 'number' then output = "Can't shift by " .. margin error(output) end if type(str) ~= 'string' then error("Нет входящей строки") elseif str:byte(1) == 43 then elseif inbord(str:byte(1),48,57) then cat = "[[Категория:Википедия:Ошибка в часовом поясе НП]]" elseif str:byte(1) == 45 or string.sub(str,1,3) == "−" or string.sub(str,1,1)=="-" then d = -1 else error(string.char(str:byte(1)) .. " недопустимый первый символ") end -- parsing input for num in string.gmatch(str,"(%d+)") do table.insert(nums,purif(num)) end if #nums > 2 then error("Ожидается всего 2 числа, а не " .. #nums) elseif #nums == 0 then error("Необходимо что-то ввести") elseif #nums == 1 then if inbord(nums[1],0,14) then timedec = d*nums[1] + margin else error("Только часы от -14 до 14") end elseif #nums == 2 then if not inbord(nums[1],0,14) then error("Только часы от -14 до 14") elseif not inbord(nums[2],0,59) then error("Минуты только от 0 до 59") else timedec = d*(nums[1] + nums[2]/60) + margin end end if tonumber(timedec) == purif(timedec) then hmarg = timedec else local h, m = math.modf(math.abs(timedec)) hmarg = h mmarg = math.floor(m*60) end if timedec == 0 then dchar = "±" elseif timedec > 0 then elseif timedec < 0 then dchar = "&minus;" end -- output output = beginning .. dchar .. math.abs(hmarg) .. ":" .. string.format("%02d",mmarg) .. ending .. cat return output end -- 60) Блок функций ввода-вывода function p.NthDay( frame ) local args = getArgs(frame, { frameOnly = true }) local num, wday, mont, yea, format = purif(args[1]), purif(args[2]), purif(args[3]), purif(args[4]), args[5] if not format then format = "%d.%m.%y" end if not inbord(num,-5,5) then return error("The number must be between -5 and 5") elseif num == 0 then return error("The number must not be zero") end if not inbord(wday,0,6) then return error("The day of the week must be between 0 and 6") end if not inbord(mont,1,12) then return error("The month must be between 1 and 12") end if not inbord(yea,0,9999) then return error("Wrong year number") end if inbord(num,1,5) then local m_start = os.time{year=yea, month=mont, day=1, hour=0} local m_wds = tonumber(os.date("%w", m_start)) local start_shift = ( (num - bool_to_number[wday >= m_wds]) * 7 - (m_wds - wday) ) * 24 * 60 * 60 local tim = m_start + start_shift if tonumber(os.date("%m", tim)) == mont then return (os.date(format, tim)) else return (err) end elseif inbord(num,-5,-1) then local m_end = os.time{year = yea, month = mont + 1, day = 1, hour = 0} - 24 * 60 * 60 local m_wde = tonumber(os.date("%w", m_end)) local end_shift = ((math.abs(num + 1) + bool_to_number[wday > m_wde]) * 7 + (m_wde - wday)) * 24 * 60 * 60 local tim = m_end - end_shift if tonumber(os.date("%m", tim)) == mont then return (os.date(format, tim)) else return (err) end end end -- =p.ToIso(mw.getCurrentFrame():newChild{title="smth",args={"12 декабря 2020"}}) -- =p.ToIso(mw.getCurrentFrame():newChild{title="smth",args={"1.2.1602"}}) -- =p.ToIso(mw.getCurrentFrame():newChild{title="smth",args={"12.12.2021"}}) -- =p.ToIso(mw.getCurrentFrame():newChild{title="smth",args={"2021.12.12"}}) function p.ToIso( frame ) local args = getArgs(frame, { frameOnly = true }) local datein = args[1] -- инициализация, заполнение обратных таблиц, копирование параметров filling_months(mnlang, month_lang) -- парсинг входящей даты по шаблону local date = parse_date(datein) if not (type(date.year) == 'number') then return ("Wrong year: " .. unwarp(date)) end if not (1 <= date.month and date.month <= 12) then return ("Wrong month: " .. unwarp(date)) end if not date.day or not (1 <= date.day and date.day <= month_end_day(date.month,date.year)) then return ("Wrong day: " .. unwarp(date)) end local timedate = os.time{year=date.year, month=date.month, day=date.day} local date = os.date("%Y-%m-%d", timedate) return date end -- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"12 декабря 2020"}}) -- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"1.2.1602"}}) -- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"декабрь 2020"}}) -- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"12-2020"}}) -- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"12.12.2021"}}) -- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"2021.12.12"}}) -- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"2021.11"}}) -- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"11.2021"}}) function p.BoxDate( frame ) local args = getArgs(frame, { frameOnly = true }) local txtDateIn, strFormat = args[1], args[2] local txtDateOut, date, status = p.bxDate(txtDateIn, strFormat, params) if status.brk then return error(status.errorText) else return txtDateOut end end function p.bxDate( txtDateIn , strFormat, params ) -- к отладке local txtDateOut, date, status = "", {}, {brk = false, errorCat = "", errorText = ""} strFormat = strFormat or "j xg Y" -- заглушка - таблица параметров на будущее params = params or {} if not txtDateIn then status.errorText = e.no_data status.errorCat = category.no_parameters status.brk = true else -- заполнение служебных таблиц filling_months(mnlang, month_lang) end if not status.brk then -- парсинг входящей даты по шаблону date = parse_date(txtDateIn) -- заменить сообщения об ошибках на списочные if not (date.year and type(date.year) == 'number') then status.errorText = string.format(e.box_date,txtDateIn) status.errorCat = category.incomplete_parameters status.brk = true end if not inbord(date.month,1,12) then status.errorText = string.format(e.box_date,txtDateIn) status.errorCat = category.incomplete_parameters status.brk = true end if not date.day and string.find(strFormat,"[dDjlNwzW]") then strFormat = trim(string.gsub(string.gsub(strFormat,"xg","F"),"[dDjlNwzW]","")) elseif not date.day then elseif not inbord(date.day,1,month_end_day(date.month,date.year)) then status.errorText = string.format(e.box_date,txtDateIn) status.errorCat = category.incomplete_parameters status.brk = true end end if not status.brk then txtDateOut = mwlang:formatDate(strFormat,tCon({date.year,date.month,date.day},"-"),true) end return txtDateOut, date, status end function p.ToDate( frame ) -- возможно неиспользуемая local args = getArgs(frame, { frameOnly = true }) local mwlang = mw.getContentLanguage() local datein = args[1] local format = "j xg Y" if not string.match(datein, "%p") then return datein elseif not args[2] then else format = args[2] end return mwlang:formatDate(format,datein,true) end -- =p.unitime(mw.getCurrentFrame():newChild{title="smth",args={"−1:30","1"}}) function p.unitime( frame ) local args = getArgs(frame, { frameOnly = true }) local DST = 0 if not args[2] then else DST = 1 end local utcin = "" local input = args[1] if not input then return "" end if inlist(input:upper(),tzs_names) then utcin = known_tzs[input:upper()] elseif (string.sub(input:upper(),1,3) == 'UTC') and (string.len(input) < 10) then utcin = string.sub(input,4) else if string.sub(input,1,1) == '[' or string.sub(input,1,1) == '{' or string.sub(input,1,1):upper() == 'U' or string.sub(input,1,1):upper() == 'M' then return input -- elseif not string.find(string.upper(string.sub(input,1,1)),"[\65-\90]") or -- not string.find(string.upper(string.sub(input,1,1)),"[\192-\223]") then -- return input else utcin = input end end -- elseif string.sub(input,1,3) ~= "−" then utcin = input -- or not (not input:find("[А-я]")) при наличии в строке юникода не работает local output = "" if DST == 0 then output = utc(utcin) else output = utc(utcin) .. ", [[летнее время|летом]] " .. utc(utcin,DST) end return output end -- УСТАРЕЛО -- =p.OldDate(mw.getCurrentFrame():newChild{title="smth",args={"20.02.2020","ю",["bc"]="1",["wd"]="1",["wy"]="1",["sq_brts"]="1",["yearmark"]="г."}}) function p.OldDate( frame ) local args = getArgs(frame, { frameOnly = true }) if not args[1] then return err end local gdate, jdate = {}, {} local strin = args[1] local cal = args[2]:lower() or "г" local bc = is(args["bc"]) local wd = is(args["wd"]) local wm = is(args["wm"]) local wy = is(args["wy"]) if not wd then wm = false end local sq_brts = is(args["sq_brts"]) local yearmark = "года" if yesno(args["yearmark"]) then elseif yesno(args["yearmark"]) == false then yearmark = "" else yearmark = trim(args["yearmark"]) or "года" end -- local infocard = is(args["infocard"]) -- local catName = args["catName"] or false local datein = numstr2date(strin) datein.year = astroyear(datein.year, bc) jdate, gdate = recalc(datein,cal) return double_couple(jdate, gdate, wd, wm, wy, sq_brts, yearmark) end -- =p.NewDate(mw.getCurrentFrame():newChild{title="Salt",args={"2020-02-20"}}) -- =p.NewDate(mw.getCurrentFrame():newChild{title="smth",args={"20.02.2020","ю",["bc"]="1",["wd"]="1",["wy"]="1",["sq_brts"]="1",["yearmark"]="г."}}) -- =p.NewDate(mw.getCurrentFrame():newChild{title="smth",args={"20.02.2020",["bc"]="0",["wd"]="1",["wy"]="1",["sq_brts"]="0",["yearmark"]=""}}) function p.NewDate( frame ) local args = getArgs(frame, { frameOnly = true }) if not args[1] then return err end local strin = args[1] local year, month, day if not not strin:match( "(-?%d%d%d%d%d)-(%d%d)-(%d%d)" ) then year, month, day = strin:match( "(-?%d%d%d%d%d)-(%d%d)-(%d%d)" ) elseif not not strin:match( "(-?%d+)-(%d+)-(%d+)" ) then year, month, day = strin:match( "(-?%d+)-(%d+)-(%d+)" ) elseif not not strin:match( "(%d%d)%.(%d%d)%.(-?%d%d%d%d%d)" ) then day, month, year = strin:match( "(%d%d)%.(%d%d)%.(-?%d%d%d%d%d)" ) elseif not not strin:match( "(%d+)%.(%d+)%.(-?%d+)" ) then day, month, year = strin:match( "(%d+)%.(%d+)%.(-?%d+)" ) end if not year then return error(args[1] .. " не подходит под форматы yyyy-mm-dd или dd.mm.yyyy") end local cal = "г" if (not args[2]) or (args[2] == "") then cal = "г" else cal = args[2]:lower() end local bc,wd,wm,wy,sq_brts = is(args["bc"]), is(args["wd"]), is(args["wd"]) and is(args["wm"]), is(args["wy"]), is(args["sq_brts"]) year = astroyear(purif(year),bc) local datein = {["year"]=purif(year), ["month"]=purif(month), ["day"]=purif(day)} local jdate, gdate = recalc(datein,cal) local yearmark = "года" local ym = args["yearmark"] or "" if yesno(ym) then elseif yesno(ym) == false then yearmark = "" else if not not ym:match("(%d+)") then error("Цифры в обозначении года: " .. ym) else yearmark = trim(ym) or "года" end end return double_couple(jdate, gdate, wd, wm, wy, sq_brts, yearmark) end -- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={}}) -- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"3","июня",nil,"21","мая"}}) -- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"28 августа","","1916 года","15"}}) -- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"3","июня","1900","21","мая"}}) -- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"6","июня","1889 год","25","мая"}}) -- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"28","ноября","1917","15"}}) -- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"28 августа","nil","1916 года","15"}}) -- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"4","января","1915","22","декабря","1914 года"}}) -- {{OldStyleDate|день (НС)|месяц (НС)|год (НС)|день (СС)|месяц (СС)|год (СС)}} function p.Test( frame ) local args = getArgs(frame, { frameOnly = true }) -- необходима проверка и замена nil на " " --[[mw.log((args[1] or "") .. " " .. (args[2] or "") .. " " .. (args[3] or "") .. " " .. (args[4] or "") .. " " .. (args[5] or "") .. " " .. (args[6] or "")) ]]-- local ingdate = triple_txt2date(args[1],args[2],args[3]) local injdate = triple_txt2date(args[4],args[5],args[6]) local j1date, g1date, j2date, g2date = init(4) mw.log("ingdate-".. (undate(ingdate) or "")) mw.log("injdate-".. (undate(injdate) or "")) local bc,wd,wm,wy,sq_brts,ny = is(args["bc"]), is(args["wd"]), is(args["wd"]) and is(args["wm"]), is(args["wy"]), is(args["sq_brts"]), is(args["ny"]) -- подавление формата для локальных тестов local wd, wm, wy = true, true, true local yearmark = "года" local ym = args["yearmark"] or ((mw.ustring.match((args[3] or ""),"(%a+)") or mw.ustring.match((args[6] or ""),"(%a+)")) or "") -- mw.log("ym " .. ym) if yesno(ym) then elseif yesno(ym) == false then yearmark = "" else if not not ym:match("(%d+)") then error("Цифры в обозначении года: " .. ym) else yearmark = trim(ym) or "года" end end if isdate(ingdate) or isdate(injdate) then if isdate(ingdate) then j1date, g1date = recalc(ingdate,"g") ingdate["full"] = true end if isdate(injdate) then j2date, g2date = recalc(injdate,"j") injdate["full"] = true end if ispartdate(ingdate) and ispartdate(injdate) then mw.log("📏 " .. dmdist(ingdate,injdate)) mw.log("📏 " .. dmdist(j1date,g1date)) mw.log("📏 " .. dmdist(j2date,g2date)) mw.log("📏 " .. dmdist(ingdate,g1date)) mw.log("📏 " .. dmdist(injdate,j2date)) end end if ny then if isyear(j1date) then else j1date["year"] = "" end if isyear(j2date) == nil then else j2date["year"] = "" end if isyear(g1date) == nil then else g1date["year"] = "" end if isyear(g2date) == nil then else g2date["year"] = "" end end if (isdate(j1date) and isdate(g1date) and isdate(j2date) and isdate(g2date)) then if ((j1date.year == j2date.year) and (j1date.month == j2date.month) and (j1date.day == j2date.day)) then return double_couple(j1date, g1date, wd, wm, wy, sq_brts, yearmark) else mw.log("📏 " .. (tostring(dmdist(ingdate,injdate)) or "")) return glue(args[1],args[2],args[3],args[4],args[5],args[6]) -- категория (предположительная разница в днях) и частичный вывод end elseif isdate(j1date) and isdate(g1date) then return double_couple(j1date, g1date, wd, wm, wy, sq_brts, yearmark) -- категория плюс частичная проверка elseif isdate(j2date) and isdate(g2date) then return double_couple(j2date, g2date, wd, wm, wy, sq_brts, yearmark) -- категория плюс частичная проверка elseif (ispartdate(ingdate) and ispartdate(injdate)) then mw.log("ingdate ".. (undate(ingdate) or "")) mw.log("injdate ".. (undate(injdate) or "")) mw.log("j1date " .. (undate(j1date ) or "")) mw.log("j2date " .. (undate(j2date ) or "")) mw.log("g1date " .. (undate(g1date ) or "")) mw.log("g2date " .. (undate(g2date ) or "")) mw.log("📏 " .. (tostring(partdist(ingdate,injdate)) or "").. " — " .. (tostring(partdist(injdate,ingdate)) or "")) return glue(args[1],args[2],args[3],args[4],args[5],args[6]) -- частичный или полный вывод, категория else mw.log("ingdate ".. (undate(ingdate) or "")) mw.log("injdate ".. (undate(injdate) or "")) mw.log("j1date " .. (undate(j1date ) or "")) mw.log("j2date " .. (undate(j2date ) or "")) mw.log("g1date " .. (undate(g1date ) or "")) mw.log("g2date " .. (undate(g2date ) or "")) return err .. category.incomplete_parameters end end return p 6b74a9b40b904aa7b7b9e465d1b64613451b5b94 Модуль:Category handler 828 31 613 414 2021-07-29T21:08:14Z ruwiki>WerySkok 0 1 версия импортирована: Импорт Инфобокса из Русскоязычной википедии. Scribunto text/plain -------------------------------------------------------------------------------- -- -- -- CATEGORY HANDLER -- -- -- -- This module implements the {{category handler}} template in Lua, -- -- with a few improvements: all namespaces and all namespace aliases -- -- are supported, and namespace names are detected automatically for -- -- the local wiki. This module requires [[Module:Namespace detect]] -- -- and [[Module:Yesno]] to be available on the local wiki. It can be -- -- configured for different wikis by altering the values in -- -- [[Module:Category handler/config]], and pages can be blacklisted -- -- from categorisation by using [[Module:Category handler/blacklist]]. -- -- -- -------------------------------------------------------------------------------- -- Load required modules local yesno = require('Module:Yesno') -- Lazily load things we don't always need local mShared, mappings local p = {} -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function trimWhitespace(s, removeBlanks) if type(s) ~= 'string' then return s end s = s:match('^%s*(.-)%s*$') if removeBlanks then if s ~= '' then return s else return nil end else return s end end -------------------------------------------------------------------------------- -- CategoryHandler class -------------------------------------------------------------------------------- local CategoryHandler = {} CategoryHandler.__index = CategoryHandler function CategoryHandler.new(data, args) local obj = setmetatable({ _data = data, _args = args }, CategoryHandler) -- Set the title object do local pagename = obj:parameter('demopage') local success, titleObj if pagename then success, titleObj = pcall(mw.title.new, pagename) end if success and titleObj then obj.title = titleObj if titleObj == mw.title.getCurrentTitle() then obj._usesCurrentTitle = true end else obj.title = mw.title.getCurrentTitle() obj._usesCurrentTitle = true end end -- Set suppression parameter values for _, key in ipairs{'nocat', 'categories'} do local value = obj:parameter(key) value = trimWhitespace(value, true) obj['_' .. key] = yesno(value) end do local subpage = obj:parameter('subpage') local category2 = obj:parameter('category2') if type(subpage) == 'string' then subpage = mw.ustring.lower(subpage) end if type(category2) == 'string' then subpage = mw.ustring.lower(category2) end obj._subpage = trimWhitespace(subpage, true) obj._category2 = trimWhitespace(category2) -- don't remove blank values end return obj end function CategoryHandler:parameter(key) local parameterNames = self._data.parameters[key] local pntype = type(parameterNames) if pntype == 'string' or pntype == 'number' then return self._args[parameterNames] elseif pntype == 'table' then for _, name in ipairs(parameterNames) do local value = self._args[name] if value ~= nil then return value end end return nil else error(string.format( 'invalid config key "%s"', tostring(key) ), 2) end end function CategoryHandler:isSuppressedByArguments() return -- See if a category suppression argument has been set. self._nocat == true or self._categories == false or ( self._category2 and self._category2 ~= self._data.category2Yes and self._category2 ~= self._data.category2Negative ) -- Check whether we are on a subpage, and see if categories are -- suppressed based on our subpage status. or self._subpage == self._data.subpageNo and self.title.isSubpage or self._subpage == self._data.subpageOnly and not self.title.isSubpage end function CategoryHandler:shouldSkipBlacklistCheck() -- Check whether the category suppression arguments indicate we -- should skip the blacklist check. return self._nocat == false or self._categories == true or self._category2 == self._data.category2Yes end function CategoryHandler:matchesBlacklist() if self._usesCurrentTitle then return self._data.currentTitleMatchesBlacklist else mShared = mShared or require('Module:Category handler/shared') return mShared.matchesBlacklist( self.title.prefixedText, mw.loadData('Module:Category handler/blacklist') ) end end function CategoryHandler:isSuppressed() -- Find if categories are suppressed by either the arguments or by -- matching the blacklist. return self:isSuppressedByArguments() or not self:shouldSkipBlacklistCheck() and self:matchesBlacklist() end function CategoryHandler:getNamespaceParameters() if self._usesCurrentTitle then return self._data.currentTitleNamespaceParameters else if not mappings then mShared = mShared or require('Module:Category handler/shared') mappings = mShared.getParamMappings(true) -- gets mappings with mw.loadData end return mShared.getNamespaceParameters( self.title, mappings ) end end function CategoryHandler:namespaceParametersExist() -- Find whether any namespace parameters have been specified. -- We use the order "all" --> namespace params --> "other" as this is what -- the old template did. if self:parameter('all') then return true end if not mappings then mShared = mShared or require('Module:Category handler/shared') mappings = mShared.getParamMappings(true) -- gets mappings with mw.loadData end for ns, params in pairs(mappings) do for i, param in ipairs(params) do if self._args[param] then return true end end end if self:parameter('other') then return true end return false end function CategoryHandler:getCategories() local params = self:getNamespaceParameters() local nsCategory for i, param in ipairs(params) do local value = self._args[param] if value ~= nil then nsCategory = value break end end if nsCategory ~= nil or self:namespaceParametersExist() then -- Namespace parameters exist - advanced usage. if nsCategory == nil then nsCategory = self:parameter('other') end local ret = {self:parameter('all')} local numParam = tonumber(nsCategory) if numParam and numParam >= 1 and math.floor(numParam) == numParam then -- nsCategory is an integer ret[#ret + 1] = self._args[numParam] else ret[#ret + 1] = nsCategory end if #ret < 1 then return nil else return table.concat(ret) end elseif self._data.defaultNamespaces[self.title.namespace] then -- Namespace parameters don't exist, simple usage. return self._args[1] end return nil end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- Used for testing purposes. return { CategoryHandler = CategoryHandler } end function p._main(args, data) data = data or mw.loadData('Module:Category handler/data') local handler = CategoryHandler.new(data, args) if handler:isSuppressed() then return nil end return handler:getCategories() end function p.main(frame, data) data = data or mw.loadData('Module:Category handler/data') local args = require('Module:Arguments').getArgs(frame, { wrappers = data.wrappers, valueFunc = function (k, v) v = trimWhitespace(v) if type(k) == 'number' then if v ~= '' then return v else return nil end else return v end end }) return p._main(args, data) end return p b74dd63857b24904ac452429b11213f18647471f Модуль:Category handler/blacklist 828 75 615 122 2021-07-29T21:08:14Z ruwiki>WerySkok 0 1 версия импортирована: Импорт Инфобокса из Русскоязычной википедии. Scribunto text/plain -- This module contains the blacklist used by [[Module:Category handler]]. -- Pages that match Lua patterns in this list will not be categorised unless -- categorisation is explicitly requested. return { '^Main Page$', -- don't categorise the main page. -- Don't categorise the following pages or their subpages. -- "%f[/\0]" matches if the next character is "/" or the end of the string. '^Wikipedia:Cascade%-protected items%f[/\0]', '^User:UBX%f[/\0]', -- The userbox "template" space. '^User talk:UBX%f[/\0]', -- Don't categorise subpages of these pages, but allow -- categorisation of the base page. '^Wikipedia:Template messages/.*$', '/[aA]rchive' -- Don't categorise archives. } c84948ad9808d5d323408d5d10d5652f748a0550 Модуль:Category handler/config 828 70 617 112 2021-07-29T21:08:15Z ruwiki>WerySkok 0 1 версия импортирована: Импорт Инфобокса из Русскоязычной википедии. Scribunto text/plain -------------------------------------------------------------------------------- -- [[Module:Category handler]] configuration data -- -- Language-specific parameter names and values can be set here. -- -- For blacklist config, see [[Module:Category handler/blacklist]]. -- -------------------------------------------------------------------------------- local cfg = {} -- Don't edit this line. -------------------------------------------------------------------------------- -- Start configuration data -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Parameter names -- -- These configuration items specify custom parameter names. -- -- To add one extra name, you can use this format: -- -- -- -- foo = 'parameter name', -- -- -- -- To add multiple names, you can use this format: -- -- -- -- foo = {'parameter name 1', 'parameter name 2', 'parameter name 3'}, -- -------------------------------------------------------------------------------- cfg.parameters = { -- The nocat and categories parameter suppress -- categorisation. They are used with Module:Yesno, and work as follows: -- -- cfg.nocat: -- Result of yesno() Effect -- true Categorisation is suppressed -- false Categorisation is allowed, and -- the blacklist check is skipped -- nil Categorisation is allowed -- -- cfg.categories: -- Result of yesno() Effect -- true Categorisation is allowed, and -- the blacklist check is skipped -- false Categorisation is suppressed -- nil Categorisation is allowed nocat = 'nocat', categories = 'categories', -- The parameter name for the legacy "category2" parameter. This skips the -- blacklist if set to the cfg.category2Yes value, and suppresses -- categorisation if present but equal to anything other than -- cfg.category2Yes or cfg.category2Negative. category2 = 'category2', -- cfg.subpage is the parameter name to specify how to behave on subpages. subpage = 'subpage', -- The parameter for data to return in all namespaces. all = 'all', -- The parameter name for data to return if no data is specified for the -- namespace that is detected. other = 'other', -- The parameter name used to specify a page other than the current page; -- used for testing and demonstration. demopage = 'page', } -------------------------------------------------------------------------------- -- Parameter values -- -- These are set values that can be used with certain parameters. Only one -- -- value can be specified, like this: -- -- -- -- cfg.foo = 'value name' -- -- -------------------------------------------------------------------------------- -- The following settings are used with the cfg.category2 parameter. Setting -- cfg.category2 to cfg.category2Yes skips the blacklist, and if cfg.category2 -- is present but equal to anything other than cfg.category2Yes or -- cfg.category2Negative then it supresses cateogrisation. cfg.category2Yes = 'yes' cfg.category2Negative = '¬' -- The following settings are used with the cfg.subpage parameter. -- cfg.subpageNo is the value to specify to not categorise on subpages; -- cfg.subpageOnly is the value to specify to only categorise on subpages. cfg.subpageNo = 'no' cfg.subpageOnly = 'only' -------------------------------------------------------------------------------- -- Default namespaces -- -- This is a table of namespaces to categorise by default. The keys are the -- -- namespace numbers. -- -------------------------------------------------------------------------------- cfg.defaultNamespaces = { [ 0] = true, -- main [ 6] = true, -- file [ 12] = true, -- help [ 14] = true, -- category [100] = true, -- portal [108] = true, -- book } -------------------------------------------------------------------------------- -- Wrappers -- -- This is a wrapper template or a list of wrapper templates to be passed to -- -- [[Module:Arguments]]. -- -------------------------------------------------------------------------------- cfg.wrappers = 'Template:Category handler' -------------------------------------------------------------------------------- -- End configuration data -- -------------------------------------------------------------------------------- return cfg -- Don't edit this line. 373cd107b13a5b00e6a1b7e66a749f12502c849d Модуль:Category handler/data 828 69 619 110 2021-07-29T21:08:15Z ruwiki>WerySkok 0 1 версия импортирована: Импорт Инфобокса из Русскоязычной википедии. Scribunto text/plain -- This module assembles data to be passed to [[Module:Category handler]] using -- mw.loadData. This includes the configuration data and whether the current -- page matches the title blacklist. local data = require('Module:Category handler/config') local mShared = require('Module:Category handler/shared') local blacklist = require('Module:Category handler/blacklist') local title = mw.title.getCurrentTitle() data.currentTitleMatchesBlacklist = mShared.matchesBlacklist( title.prefixedText, blacklist ) data.currentTitleNamespaceParameters = mShared.getNamespaceParameters( title, mShared.getParamMappings() ) return data abbc68048ff698e88dda06b64ecf384bbf583120 Модуль:Category handler/shared 828 74 621 120 2021-07-29T21:08:15Z ruwiki>WerySkok 0 1 версия импортирована: Импорт Инфобокса из Русскоязычной википедии. Scribunto text/plain -- This module contains shared functions used by [[Module:Category handler]] -- and its submodules. local p = {} function p.matchesBlacklist(page, blacklist) for i, pattern in ipairs(blacklist) do local match = mw.ustring.match(page, pattern) if match then return true end end return false end function p.getParamMappings(useLoadData) local dataPage = 'Module:Namespace detect/data' if useLoadData then return mw.loadData(dataPage).mappings else return require(dataPage).mappings end end function p.getNamespaceParameters(titleObj, mappings) -- We don't use title.nsText for the namespace name because it adds -- underscores. local mappingsKey if titleObj.isTalkPage then mappingsKey = 'talk' else mappingsKey = mw.site.namespaces[titleObj.namespace].name end mappingsKey = mw.ustring.lower(mappingsKey) return mappings[mappingsKey] or {} end return p d2d5de1a031e6ce97c242cbfa8afe7a92cb9eca5 Модуль:Message box 828 21 623 2021-07-29T21:08:16Z ruwiki>WerySkok 0 1 версия импортирована: Импорт Инфобокса из Русскоязычной википедии. Scribunto text/plain -- This is a meta-module for producing message box templates, including -- {{mbox}}, {{ambox}}, {{imbox}}, {{tmbox}}, {{ombox}}, {{cmbox}} and {{fmbox}}. -- Load necessary modules. require('Module:No globals') local getArgs local categoryHandler = require('Module:Category handler')._main local yesno = require('Module:Yesno') local boxDate = require('Module:Calendar').bxDate; -- Get a language object for formatDate and ucfirst. local lang = mw.language.getContentLanguage() -- Define constants local CONFIG_MODULE = 'Module:Message box/configuration' -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function getTitleObject(...) -- Get the title object, passing the function through pcall -- in case we are over the expensive function count limit. local success, title = pcall(mw.title.new, ...) if success then return title end end local function union(t1, t2) -- Returns the union of two arrays. local vals = {} for i, v in ipairs(t1) do vals[v] = true end for i, v in ipairs(t2) do vals[v] = true end local ret = {} for k in pairs(vals) do table.insert(ret, k) end table.sort(ret) return ret end local function getArgNums(args, prefix) local nums = {} for k, v in pairs(args) do local num = mw.ustring.match(tostring(k), '^' .. prefix .. '([1-9]%d*)$') if num then table.insert(nums, tonumber(num)) end end table.sort(nums) return nums end -- локальная обёртка, игнорирует таблицу с номерами дня, месяца и года local function formatDate(txtDateIn, strFormat, params) local txtDateOut, date, status = boxDate(txtDateIn, strFormat, params) if status.brk then return error(status.errorText) else return txtDateOut end end -------------------------------------------------------------------------------- -- Box class definition -------------------------------------------------------------------------------- local MessageBox = {} MessageBox.__index = MessageBox function MessageBox.new(boxType, args, cfg) args = args or {} local obj = {} -- Set the title object and the namespace. obj.title = getTitleObject(args.page) or mw.title.getCurrentTitle() -- Set the config for our box type. obj.cfg = cfg[boxType] if not obj.cfg then local ns = obj.title.namespace -- boxType is "mbox" or invalid input if ns == 0 then obj.cfg = cfg.ambox -- main namespace elseif ns == 6 then obj.cfg = cfg.imbox -- file namespace elseif ns == 14 then obj.cfg = cfg.cmbox -- category namespace else local nsTable = mw.site.namespaces[ns] if nsTable and nsTable.isTalk then obj.cfg = cfg.tmbox -- any talk namespace else obj.cfg = cfg.ombox -- other namespaces or invalid input end end end -- Set the arguments, and remove all blank arguments except for the ones -- listed in cfg.allowBlankParams. do local newArgs = {} for k, v in pairs(args) do if v ~= '' then newArgs[k] = v end end for i, param in ipairs(obj.cfg.allowBlankParams or {}) do newArgs[param] = args[param] end obj.args = newArgs end -- Define internal data structure. obj.categories = {} obj.classes = {} return setmetatable(obj, MessageBox) end function MessageBox:addCat(ns, cat, sort) if not cat then return nil end if sort then cat = string.format('[[Категория:%s|%s]]', cat, sort) else cat = string.format('[[Категория:%s]]', cat) end self.categories[ns] = self.categories[ns] or {} table.insert(self.categories[ns], cat) end function MessageBox:addClass(class) if not class then return nil end table.insert(self.classes, class) end function MessageBox:setParameters() local args = self.args local cfg = self.cfg -- Get type data. self.type = args.type local typeData = cfg.types[self.type] self.invalidTypeError = cfg.showInvalidTypeError and self.type and not typeData typeData = typeData or cfg.types[cfg.default] self.typeClass = typeData.class self.typeImage = typeData.image -- Find if the box has been wrongly substituted. self.isSubstituted = cfg.substCheck and args.subst == 'SUBST' -- Find whether we are using a small message box. self.isSmall = cfg.allowSmall and ( cfg.smallParam and args.small == cfg.smallParam or not cfg.smallParam and yesno(args.small) ) -- Add attributes, classes and styles. self.id = args.id if yesno(args.plainlinks) ~= false then self:addClass('plainlinks') end if args.mini then self:addClass('ambox-mini') end for _, class in ipairs(cfg.classes or {}) do self:addClass(class) end if self.isSmall then self:addClass(cfg.smallClass or 'mbox-small') end self:addClass(self.typeClass) self:addClass(args.class) self.style = args.style self.attrs = args.attrs self.dataLabel1 = args['data-label-1'] self.dataLabel2 = args['data-label-2'] self.dataLabel3 = args['data-label-3'] self.dataValue1 = args['data-value-1'] self.dataValue2 = args['data-value-2'] self.dataValue3 = args['data-value-3'] -- Set text style. self.textstyle = args.textstyle -- Find if we are on the template page or not. This functionality is only -- used if useCollapsibleTextFields is set, or if both cfg.templateCategory -- and cfg.templateCategoryRequireName are set. self.useCollapsibleTextFields = cfg.useCollapsibleTextFields if self.useCollapsibleTextFields or cfg.templateCategory and cfg.templateCategoryRequireName then self.name = args.name if self.name then local templateName = mw.ustring.match( self.name, '^[tT][eE][mM][pP][lL][aA][tT][eE][%s_]*:[%s_]*(.*)$' ) or self.name templateName = ('Template:' .. templateName) or ('Шаблон:' .. templateName) self.templateTitle = getTitleObject(templateName) end self.isTemplatePage = self.templateTitle and mw.title.equals(self.title, self.templateTitle) end -- Process data for collapsible text fields. At the moment these are only -- used in {{ambox}}. if self.useCollapsibleTextFields then -- Get the self.issue value. if self.isSmall and args.smalltext then self.issue = args.smalltext else local sect if args.sect == '' then sect = '<span style="font-weight:bold">Эта ' .. (cfg.sectionDefault or 'статья') .. '</span>' elseif type(args.sect) == 'string' then sect = '<span style="font-weight:bold">' .. args.sect .. '</span>' end local issue = args.issue issue = type(issue) == 'string' and issue ~= '' and issue or nil local text = args.text text = type(text) == 'string' and text or nil local issues = {} table.insert(issues, sect) table.insert(issues, issue) table.insert(issues, text) self.issue = table.concat(issues, ' ') end -- Get the self.talk value. local talk = args.talk -- Show talk links on the template page or template subpages if the talk -- parameter is blank. if talk == '' and self.templateTitle and ( mw.title.equals(self.templateTitle, self.title) or self.title:isSubpageOf(self.templateTitle) ) then talk = '#' elseif talk == '' then talk = nil end if talk then -- If the talk value is a talk page, make a link to that page. Else -- assume that it's a section heading, and make a link to the talk -- page of the current page with that section heading. local talkTitle = getTitleObject(talk) local talkArgIsTalkPage = true if not talkTitle or not talkTitle.isTalkPage then talkArgIsTalkPage = false talkTitle = getTitleObject( self.title.text, mw.site.namespaces[self.title.namespace].talk.id ) end if talkTitle and talkTitle.exists then local talkText = 'Соответствующую дискуссию можно найти на' if talkArgIsTalkPage then talkText = string.format( '%s [[%s|%s]].', talkText, talk, talkTitle.prefixedText ) else talkText = string.format( '%s [[%s#%s|странице обсуждения]].', talkText, talkTitle.prefixedText, talk ) end self.talk = talkText end end -- Get other values. self.fix = args.fix ~= '' and args.fix or nil local date if args.date and args.date ~= '' then local status, result = pcall(formatDate, args.date) if status then date = string.format("(<span class='date'>%s</span>)", result) else date = string.format("<span class='error'>(Строка «%s» не является верной датой, пожалуйста, укажите дату в формате <code>ГГГГ-ММ-ДД</code>)</span>", args.date) end elseif args.date == '' and self.isTemplatePage then date = string.format("(<span class='date'>%s</span>)", formatDate( lang:formatDate('Y-m-d') ) ) -- тут возникновения ошибки, связанной с пользовательским вводом, не будет end if date then self.date = string.format(" <span class='mbox-date'>''%s''</span>", date) end self.info = args.info if yesno(args.removalnotice) then self.removalNotice = cfg.removalNotice end if args.shortFix then self.shortFix = args.shortFix end end -- Set the non-collapsible text field. At the moment this is used by all box -- types other than ambox, and also by ambox when small=yes. if self.isSmall then self.text = args.smalltext or args.text else self.text = args.text self.textsmall = args['text-small'] end -- Set the below row. self.below = cfg.below and args.below -- General image settings. self.imageCellDiv = not self.isSmall and cfg.imageCellDiv self.imageEmptyCell = cfg.imageEmptyCell if cfg.imageEmptyCellStyle then self.imageEmptyCellStyle = 'border:none;padding:0px;width:1px' end -- Left image settings. local imageLeft = self.isSmall and args.smallimage or args.image if cfg.imageCheckBlank and imageLeft ~= 'blank' and imageLeft ~= 'none' and imageLeft ~= '' or not cfg.imageCheckBlank and imageLeft ~= 'none' then self.imageLeft = imageLeft if not imageLeft then local imageSize = self.isSmall and (cfg.imageSmallSize or '30x30px') or cfg.imageSize or '40x40px' self.imageLeft = string.format('[[File:%s|%s|alt=]]', self.typeImage or 'Information icon4.svg', imageSize) end end -- Right image settings. local imageRight = self.isSmall and args.smallimageright or args.imageright if not (cfg.imageRightNone and imageRight == 'none') then self.imageRight = imageRight end end function MessageBox:setMainspaceCategories() local args = self.args local cfg = self.cfg local date = nil if not cfg.allowMainspaceCategories then return nil end local nums = {} for _, prefix in ipairs{'cat', 'category', 'all'} do args[prefix .. '1'] = args[prefix] nums = union(nums, getArgNums(args, prefix)) end -- The following is roughly equivalent to the old {{Ambox/category}}. local status, result = pcall(formatDate, args.date, 'xg Y') if status then date = result end date = type(date) == 'string' and date local preposition = 'с' local suffix = 'года' for _, num in ipairs(nums) do local mainCat = args['cat' .. tostring(num)] or args['category' .. tostring(num)] local allCat = args['all' .. tostring(num)] mainCat = type(mainCat) == 'string' and mainCat allCat = type(allCat) == 'string' and allCat if mainCat and date and date ~= '' then local catTitle = string.format('%s %s %s %s', mainCat, preposition, date, suffix) self:addCat(0, catTitle) catTitle = getTitleObject('Категория:' .. catTitle) local status, result = pcall(formatDate, args.date) if not status then self:addCat(0, 'Википедия:Статьи с недопустимым параметром даты в шаблоне-сообщении') end elseif mainCat and (not date or date == '') then self:addCat(0, mainCat) end if allCat then self:addCat(0, allCat) end end end function MessageBox:setTemplateCategories() local args = self.args local cfg = self.cfg -- Add template categories. if cfg.templateCategory then if cfg.templateCategoryRequireName then if self.isTemplatePage then self:addCat(10, cfg.templateCategory) end elseif not self.title.isSubpage then self:addCat(10, cfg.templateCategory) end end -- Add template error categories. if cfg.templateErrorCategory then local templateErrorCategory = cfg.templateErrorCategory local templateCat, templateSort if not self.name and not self.title.isSubpage then templateCat = templateErrorCategory elseif self.isTemplatePage then local paramsToCheck = cfg.templateErrorParamsToCheck or {} local count = 0 for i, param in ipairs(paramsToCheck) do if not args[param] then count = count + 1 end end if count > 0 then templateCat = templateErrorCategory templateSort = tostring(count) end if self.categoryNums and #self.categoryNums > 0 then templateCat = templateErrorCategory templateSort = 'C' end end self:addCat(10, templateCat, templateSort) end end function MessageBox:setAllNamespaceCategories() -- Set categories for all namespaces. if self.invalidTypeError then local allSort = (self.title.namespace == 0 and 'Main:' or '') .. self.title.prefixedText self:addCat('all', 'Википедия:Необходимо исправить параметр в шаблоне-сообщении', allSort) end if self.isSubstituted then self:addCat('all', 'Википедия:Страницы с ошибочно подставленными шаблонами') end end function MessageBox:setCategories() if self.title.namespace == 0 then self:setMainspaceCategories() elseif self.title.namespace == 10 then self:setTemplateCategories() end self:setAllNamespaceCategories() end function MessageBox:renderCategories() -- Convert category tables to strings and pass them through -- [[Module:Category handler]]. return categoryHandler{ main = table.concat(self.categories[0] or {}), template = table.concat(self.categories[10] or {}), all = table.concat(self.categories.all or {}), nocat = self.args.nocat, page = self.args.page } end function MessageBox:export() local root = mw.html.create() -- Add the subst check error. if self.isSubstituted and self.name then root:tag('b') :addClass('error') :wikitext(string.format( 'Шаблон <code>%s[[Шаблон:%s|%s]]%s</code> был неккоректно подставлен.', mw.text.nowiki('{{'), self.name, self.name, mw.text.nowiki('}}') )) end -- Create the box table. local boxTable = root:tag('table') boxTable:attr('id', self.id or nil) for i, class in ipairs(self.classes or {}) do boxTable:addClass(class or nil) end boxTable :cssText(self.style or nil) :attr('role', 'presentation') if self.dataLabel1 then boxTable:attr('data-' .. self.dataLabel1, self.dataValue1) end if self.dataLabel2 then boxTable:attr('data-' .. self.dataLabel2, self.dataValue2) end if self.dataLabel3 then boxTable:attr('data-' .. self.dataLabel3, self.dataValue3) end if self.attrs then boxTable:attr(self.attrs) end -- Add the left-hand image. local row = boxTable:tag('tr') if self.imageLeft then local imageLeftCell = row:tag('td'):addClass('mbox-image') if self.imageCellDiv then -- If we are using a div, redefine imageLeftCell so that the image -- is inside it. Divs use style="width: 52px;", which limits the -- image width to 52px. If any images in a div are wider than that, -- they may overlap with the text or cause other display problems. imageLeftCell = imageLeftCell:tag('div'):css('width', '52px') end imageLeftCell:wikitext(self.imageLeft or nil) elseif self.imageEmptyCell then -- Some message boxes define an empty cell if no image is specified, and -- some don't. The old template code in templates where empty cells are -- specified gives the following hint: "No image. Cell with some width -- or padding necessary for text cell to have 100% width." row:tag('td') :addClass('mbox-empty-cell') :cssText(self.imageEmptyCellStyle or nil) end -- Add the text. local textCell = row:tag('td'):addClass('mbox-text') if self.useCollapsibleTextFields then -- The message box uses advanced text parameters that allow things to be -- collapsible. At the moment, only ambox uses this. textCell:cssText(self.textstyle or nil) local textCellDiv = textCell:tag('div') textCellDiv :addClass('mbox-text-div') :wikitext(self.issue or nil) local textsmallCellDiv = textCell:tag('div') textsmallCellDiv :addClass('mbox-textsmall-div hide-when-compact') :cssText(self.textsmallstyle or 'font-size:85%') :wikitext(self.textsmall or nil) if (self.talk or self.fix) and not self.isSmall then textsmallCellDiv:tag('span') :addClass('hide-when-compact') :wikitext(self.talk and (' ' .. self.talk) or nil) :wikitext(self.fix and (' ' .. self.fix) or nil) end textsmallCellDiv:wikitext(self.date and (' ' .. self.date) or nil) if self.info and not self.isSmall then textsmallCellDiv :tag('span') :addClass('hide-when-compact') :wikitext(self.info and (' ' .. self.info) or nil) end if self.removalNotice then textsmallCellDiv:tag('small') :addClass('hide-when-compact') :tag('i') :wikitext(string.format(" (%s)", self.removalNotice)) end if self.shortFix then textCell:tag('div') :addClass('mbox-multiply') :tag('span') :wikitext(string.format("%s", self.shortFix)) :tag('span') :wikitext(self.date and (' ' .. self.date) or nil) end else -- Default text formatting - anything goes. textCell :cssText(self.textstyle or nil) :wikitext(self.text or nil) end -- Add the right-hand image. if self.imageRight then local imageRightCell = row:tag('td'):addClass('mbox-imageright') if self.imageCellDiv then -- If we are using a div, redefine imageRightCell so that the image -- is inside it. imageRightCell = imageRightCell:tag('div'):css('width', '52px') end imageRightCell :wikitext(self.imageRight or nil) end -- Add the below row. if self.below then boxTable:tag('tr') :tag('td') :attr('colspan', self.imageRight and '3' or '2') :addClass('mbox-text') :cssText(self.textstyle or nil) :wikitext(self.below or nil) end -- Add error message for invalid type parameters. if self.invalidTypeError then root:tag('div') :css('text-align', 'center') :wikitext(string.format( 'Этот шаблон-сообщение использует неверный параметр "type=%s", необходимо исправить.', self.type or '' )) end -- Add categories. root:wikitext(self:renderCategories() or nil) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p, mt = {}, {} function p._exportClasses() -- For testing. return { MessageBox = MessageBox } end function p.main(boxType, args, cfgTables) local box = MessageBox.new(boxType, args, cfgTables or mw.loadData(CONFIG_MODULE)) box:setParameters() box:setCategories() return box:export() end function mt.__index(t, k) return function (frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end return t.main(k, getArgs(frame, {trim = false, removeBlanks = false})) end end return setmetatable(p, mt) f7438b70acb7f9253502968228af5c073b3b1ca5 Модуль:Message box/configuration 828 67 625 2021-07-29T21:08:17Z ruwiki>WerySkok 0 1 версия импортирована: Импорт Инфобокса из Русскоязычной википедии. Scribunto text/plain -------------------------------------------------------------------------------- -- Message box configuration -- -- -- -- This module contains configuration data for [[Module:Message box]]. -- -------------------------------------------------------------------------------- return { ambox = { types = { speedy = { class = 'ambox-speedy', image = 'Ambox warning pn.svg' }, delete = { class = 'ambox-delete', image = 'Stop hand nuvola.svg' }, content = { class = 'ambox-content', image = 'Emblem-important.svg' }, style = { class = 'ambox-style', image = 'Broom_icon.svg' }, move = { class = 'ambox-move', image = 'Merge-split-transwiki default.svg' }, protection = { class = 'ambox-protection', image = 'Padlock-silver-medium.svg' }, notice = { class = 'ambox-notice', image = 'Information.svg' }, good = { class = 'ambox-good', image = 'Green star boxed.svg' }, serious = { class = 'ambox-serious', image = 'Stop hand nuvola.svg' }, merge = { class = 'ambox-merge', image = 'Merge-split-transwiki default.svg' }, discussion = { class = 'ambox-discussion', image = 'Nuvola apps ksirc.png' } }, default = 'notice', allowBlankParams = {'talk', 'sect', 'date', 'issue', 'fix', 'subst', 'hidden', 'image'}, allowSmall = true, smallParam = 'left', smallClass = 'mbox-small-left', substCheck = true, classes = {'metadata', 'ambox'}, imageEmptyCell = true, imageCheckBlank = true, imageSmallSize = '20x20px', imageCellDiv = true, useCollapsibleTextFields = true, imageRightNone = true, sectionDefault = 'статья', allowMainspaceCategories = true, templateCategory = 'Шаблоны:Шаблоны-сообщения для статей', templateCategoryRequireName = true, templateErrorCategory = 'Шаблоны:Шаблоны-сообщения для статей с пропущенными параметрами', templateErrorParamsToCheck = {'issue', 'fix'}, removalNotice = '[[Help:Maintenance template removal|Learn how and when to remove this template message]]' }, cmbox = { types = { speedy = { class = 'cmbox-speedy', image = 'Ambox warning pn.svg' }, delete = { class = 'cmbox-delete', image = 'Ambox warning pn.svg' }, content = { class = 'cmbox-content', image = 'Ambox important.svg' }, style = { class = 'cmbox-style', image = 'Edit-clear.svg' }, move = { class = 'cmbox-move', image = 'Merge-split-transwiki default.svg' }, protection = { class = 'cmbox-protection', image = 'Padlock-silver-medium.svg' }, notice = { class = 'cmbox-notice', image = 'Information icon4.svg' } }, default = 'notice', showInvalidTypeError = true, classes = {'cmbox'}, imageEmptyCell = true, useCollapsibleTextFields = true }, fmbox = { types = { warning = { class = 'fmbox-warning', image = 'Ambox warning pn.svg' }, editnotice = { class = 'fmbox-editnotice', image = 'Information icon4.svg' }, system = { class = 'fmbox-system', image = 'Information icon4.svg' } }, default = 'system', showInvalidTypeError = true, classes = {'fmbox'}, imageEmptyCell = false, imageRightNone = false, useCollapsibleTextFields = true }, imbox = { types = { speedy = { class = 'imbox-speedy', image = 'Ambox warning pn.svg' }, delete = { class = 'imbox-delete', image = 'Ambox warning pn.svg' }, content = { class = 'imbox-content', image = 'Ambox important.svg' }, style = { class = 'imbox-style', image = 'Edit-clear.svg' }, move = { class = 'imbox-move', image = 'Merge-split-transwiki default.svg' }, protection = { class = 'imbox-protection', image = 'Padlock-silver-medium.svg' }, license = { class = 'imbox-license licensetpl', image = 'Imbox license.png' -- @todo We need an SVG version of this }, featured = { class = 'imbox-featured', image = 'Cscr-featured.svg' }, notice = { class = 'imbox-notice', image = 'Information icon4.svg' } }, default = 'notice', showInvalidTypeError = true, classes = {'imbox'}, imageEmptyCell = true, below = true, useCollapsibleTextFields = true, templateCategory = 'Шаблоны:Шаблоны-сообщения для файлов' }, ombox = { types = { speedy = { class = 'ombox-speedy', image = 'OOjs UI icon alert-destructive.svg' }, delete = { class = 'ombox-delete', image = 'OOjs UI icon alert-destructive.svg' }, content = { class = 'ombox-content', image = 'OOjs UI icon notice-warning.svg' }, style = { class = 'ombox-style', image = 'Edit-clear.svg' }, move = { class = 'ombox-move', image = 'Imbox move.png' }, protection = { class = 'ombox-protection', image = 'Imbox protection.png' }, notice = { class = 'ombox-notice', image = 'OOjs UI icon info-progressive.svg' } }, default = 'notice', showInvalidTypeError = true, classes = {'ombox'}, allowSmall = true, imageEmptyCell = true, imageRightNone = true, useCollapsibleTextFields = true }, tmbox = { types = { speedy = { class = 'tmbox-speedy', image = 'Ambox warning pn.svg' }, delete = { class = 'tmbox-delete', image = 'Ambox warning pn.svg' }, content = { class = 'tmbox-content', image = 'Ambox important.svg' }, style = { class = 'tmbox-style', image = 'Edit-clear.svg' }, move = { class = 'tmbox-move', image = 'Merge-split-transwiki default.svg' }, protection = { class = 'tmbox-protection', image = 'Padlock-silver-medium.svg' }, notice = { class = 'tmbox-notice', image = 'Information icon4.svg' } }, default = 'notice', showInvalidTypeError = true, classes = {'tmbox'}, allowSmall = true, imageRightNone = true, imageEmptyCell = true, imageEmptyCellStyle = true, useCollapsibleTextFields = true, templateCategory = 'Шаблоны:Шаблоны-сообщения для страниц обсуждений' } } 569b6dcbf9ec9858c77ddf8aefe198cd3f90a950 Модуль:Namespace detect/config 828 77 627 126 2021-07-29T21:08:18Z ruwiki>WerySkok 0 1 версия импортирована: Импорт Инфобокса из Русскоязычной википедии. Scribunto text/plain -------------------------------------------------------------------------------- -- Namespace detect configuration data -- -- -- -- This module stores configuration data for Module:Namespace detect. Here -- -- you can localise the module to your wiki's language. -- -- -- -- To activate a configuration item, you need to uncomment it. This means -- -- that you need to remove the text "-- " at the start of the line. -- -------------------------------------------------------------------------------- local cfg = {} -- Don't edit this line. -------------------------------------------------------------------------------- -- Parameter names -- -- These configuration items specify custom parameter names. Values added -- -- here will work in addition to the default English parameter names. -- -- To add one extra name, you can use this format: -- -- -- -- cfg.foo = 'parameter name' -- -- -- -- To add multiple names, you can use this format: -- -- -- -- cfg.foo = {'parameter name 1', 'parameter name 2', 'parameter name 3'} -- -------------------------------------------------------------------------------- ---- This parameter displays content for the main namespace: -- cfg.main = 'main' ---- This parameter displays in talk namespaces: -- cfg.talk = 'talk' ---- This parameter displays content for "other" namespaces (namespaces for which ---- parameters have not been specified): -- cfg.other = 'other' ---- This parameter makes talk pages behave as though they are the corresponding ---- subject namespace. Note that this parameter is used with [[Module:Yesno]]. ---- Edit that module to change the default values of "yes", "no", etc. -- cfg.subjectns = 'subjectns' ---- This parameter sets a demonstration namespace: -- cfg.demospace = 'demospace' ---- This parameter sets a specific page to compare: cfg.demopage = 'page' -------------------------------------------------------------------------------- -- Table configuration -- -- These configuration items allow customisation of the "table" function, -- -- used to generate a table of possible parameters in the module -- -- documentation. -- -------------------------------------------------------------------------------- ---- The header for the namespace column in the wikitable containing the list of ---- possible subject-space parameters. -- cfg.wikitableNamespaceHeader = 'Namespace' ---- The header for the wikitable containing the list of possible subject-space ---- parameters. -- cfg.wikitableAliasesHeader = 'Aliases' -------------------------------------------------------------------------------- -- End of configuration data -- -------------------------------------------------------------------------------- return cfg -- Don't edit this line. 0e4ff08d13c4b664d66b32c232deb129b77c1a56 Модуль:Namespace detect/data 828 76 629 124 2021-07-29T21:08:19Z ruwiki>WerySkok 0 1 версия импортирована: Импорт Инфобокса из Русскоязычной википедии. Scribunto text/plain -------------------------------------------------------------------------------- -- Namespace detect data -- -- This module holds data for [[Module:Namespace detect]] to be loaded per -- -- page, rather than per #invoke, for performance reasons. -- -------------------------------------------------------------------------------- local cfg = require('Module:Namespace detect/config') local function addKey(t, key, defaultKey) if key ~= defaultKey then t[#t + 1] = key end end -- Get a table of parameters to query for each default parameter name. -- This allows wikis to customise parameter names in the cfg table while -- ensuring that default parameter names will always work. The cfg table -- values can be added as a string, or as an array of strings. local defaultKeys = { 'main', 'talk', 'other', 'subjectns', 'demospace', 'demopage' } local argKeys = {} for i, defaultKey in ipairs(defaultKeys) do argKeys[defaultKey] = {defaultKey} end for defaultKey, t in pairs(argKeys) do local cfgValue = cfg[defaultKey] local cfgValueType = type(cfgValue) if cfgValueType == 'string' then addKey(t, cfgValue, defaultKey) elseif cfgValueType == 'table' then for i, key in ipairs(cfgValue) do addKey(t, key, defaultKey) end end cfg[defaultKey] = nil -- Free the cfg value as we don't need it any more. end local function getParamMappings() --[[ -- Returns a table of how parameter names map to namespace names. The keys -- are the actual namespace names, in lower case, and the values are the -- possible parameter names for that namespace, also in lower case. The -- table entries are structured like this: -- { -- [''] = {'main'}, -- ['wikipedia'] = {'wikipedia', 'project', 'wp'}, -- ... -- } --]] local mappings = {} local mainNsName = mw.site.subjectNamespaces[0].name mainNsName = mw.ustring.lower(mainNsName) mappings[mainNsName] = mw.clone(argKeys.main) mappings['talk'] = mw.clone(argKeys.talk) for nsid, ns in pairs(mw.site.subjectNamespaces) do if nsid ~= 0 then -- Exclude main namespace. local nsname = mw.ustring.lower(ns.name) local canonicalName = mw.ustring.lower(ns.canonicalName) mappings[nsname] = {nsname} if canonicalName ~= nsname then table.insert(mappings[nsname], canonicalName) end for _, alias in ipairs(ns.aliases) do table.insert(mappings[nsname], mw.ustring.lower(alias)) end end end return mappings end return { argKeys = argKeys, cfg = cfg, mappings = getParamMappings() } d224f42a258bc308ef3ad8cc8686cd7a4f47d005 Модуль:No globals 828 251 607 2021-07-29T21:08:20Z ruwiki>WerySkok 0 1 версия импортирована: Импорт Инфобокса из Русскоязычной википедии. Scribunto text/plain local mt = getmetatable(_G) or {} function mt.__index (t, k) if k ~= 'arg' then error('Tried to read nil global ' .. tostring(k), 2) end return nil end function mt.__newindex(t, k, v) if k ~= 'arg' then error('Tried to write global ' .. tostring(k), 2) end rawset(t, k, v) end setmetatable(_G, mt) 8ce3969f7d53b08bd00dabe4cc9780bc6afd412a Модуль:Separated entries 828 158 565 358 2021-07-29T21:08:21Z ruwiki>WerySkok 0 1 версия импортирована: Импорт Инфобокса из Русскоязычной википедии. Scribunto text/plain -- This module takes positional parameters as input and concatenates them with -- an optional separator. The final separator (the "conjunction") can be -- specified independently, enabling natural-language lists like -- "foo, bar, baz and qux". local compressSparseArray = require('Module:TableTools').compressSparseArray local p = {} function p._main(args) local separator = args.separator -- Decode (convert to Unicode) HTML escape sequences, such as "&#32;" for space. and mw.text.decode(args.separator) or '' local conjunction = args.conjunction and mw.text.decode(args.conjunction) or separator -- Discard named parameters. local values = compressSparseArray(args) return mw.text.listToText(values, separator, conjunction) end local function makeInvokeFunction(separator, conjunction) return function (frame) local args = require('Module:Arguments').getArgs(frame) args.separator = separator or args.separator args.conjunction = conjunction or args.conjunction return p._main(args) end end p.main = makeInvokeFunction() p.br = makeInvokeFunction('<br />') p.newline = makeInvokeFunction('\n') p.comma = makeInvokeFunction(mw.message.new('comma-separator'):plain()) return p 33a68f0a46d62c42b6523a548f0f881e82ecfe58 Модуль:String 828 138 567 318 2021-07-29T21:08:21Z ruwiki>WerySkok 0 1 версия импортирована: Импорт Инфобокса из Русскоязычной википедии. Scribunto text/plain --[[ This module is intended to provide access to basic string functions. Most of the functions provided here can be invoked with named parameters, unnamed parameters, or a mixture. If named parameters are used, Mediawiki will automatically remove any leading or trailing whitespace from the parameter. Depending on the intended use, it may be advantageous to either preserve or remove such whitespace. Global options ignore_errors: If set to 'true' or 1, any error condition will result in an empty string being returned rather than an error message. error_category: If an error occurs, specifies the name of a category to include with the error message. The default category is [Category:Errors reported by Module String]. no_category: If set to 'true' or 1, no category will be added if an error is generated. Unit tests for this module are available at Module:String/tests. ]] local str = {} --[[ subcount This function returns the count of substring in source string. Usage: {{#invoke:String|subcount|source_string|substring|plain_flag}} OR {{#invoke:String|subcount|s=source_string|pattern=substring|plain=plain_flag}} Parameters s: The string to search pattern: The pattern or string to find within the string plain: A flag indicating that the substring should be understood as plain text. Defaults to true. If invoked using named parameters, Mediawiki will automatically remove any leading or trailing whitespace from the target string. ]] function str.subcount( frame ) local new_args = str._getParameters( frame.args, {'s', 'pattern', 'plain'} ); local s = new_args['s'] or ''; local plain_flag = str._getBoolean( new_args['plain'] or true ); local pattern = new_args['pattern'] or ''; if s == '' or pattern == '' then return 0; end if plain_flag then pattern = str._escapePattern( pattern ); end local _, count = mw.ustring.gsub(s, pattern, "") return count; end --[[ len This function returns the length of the target string. Usage: {{#invoke:String|len|target_string|}} OR {{#invoke:String|len|s=target_string}} Parameters s: The string whose length to report If invoked using named parameters, Mediawiki will automatically remove any leading or trailing whitespace from the target string. ]] function str.len( frame ) local new_args = str._getParameters( frame.args, {'s'} ); local s = new_args['s'] or ''; return mw.ustring.len( s ) end --[[ sub This function returns a substring of the target string at specified indices. Usage: {{#invoke:String|sub|target_string|start_index|end_index}} OR {{#invoke:String|sub|s=target_string|i=start_index|j=end_index}} Parameters s: The string to return a subset of i: The fist index of the substring to return, defaults to 1. j: The last index of the string to return, defaults to the last character. The first character of the string is assigned an index of 1. If either i or j is a negative value, it is interpreted the same as selecting a character by counting from the end of the string. Hence, a value of -1 is the same as selecting the last character of the string. If the requested indices are out of range for the given string, an error is reported. ]] function str.sub( frame ) local new_args = str._getParameters( frame.args, { 's', 'i', 'j' } ); local s = new_args['s'] or ''; local i = tonumber( new_args['i'] ) or 1; local j = tonumber( new_args['j'] ) or -1; local len = mw.ustring.len( s ); -- Convert negatives for range checking if i < 0 then i = len + i + 1; end if j < 0 then j = len + j + 1; end if i > len or j > len or i < 1 or j < 1 then return str._error( 'Значение индекса подстроки выходит за допустимые границы' ); end if j < i then return str._error( 'Неверный порядок индексов подстроки' ); end return mw.ustring.sub( s, i, j ) end --[[ This function implements that features of {{str sub old}} and is kept in order to maintain these older templates. ]] function str.sublength( frame ) local i = tonumber( frame.args.i ) or 0 local len = tonumber( frame.args.len ) return mw.ustring.sub( frame.args.s, i + 1, len and ( i + len ) ) end --[[ match This function returns a substring from the source string that matches a specified pattern. Usage: {{#invoke:String|match|source_string|pattern_string|start_index|match_number|plain_flag|nomatch_output}} OR {{#invoke:String|pos|s=source_string|pattern=pattern_string|start=start_index |match=match_number|plain=plain_flag|nomatch=nomatch_output}} Parameters s: The string to search pattern: The pattern or string to find within the string start: The index within the source string to start the search. The first character of the string has index 1. Defaults to 1. match: In some cases it may be possible to make multiple matches on a single string. This specifies which match to return, where the first match is match= 1. If a negative number is specified then a match is returned counting from the last match. Hence match = -1 is the same as requesting the last match. Defaults to 1. plain: A flag indicating that the pattern should be understood as plain text. Defaults to false. nomatch: If no match is found, output the "nomatch" value rather than an error. If invoked using named parameters, Mediawiki will automatically remove any leading or trailing whitespace from each string. In some circumstances this is desirable, in other cases one may want to preserve the whitespace. If the match_number or start_index are out of range for the string being queried, then this function generates an error. An error is also generated if no match is found. If one adds the parameter ignore_errors=true, then the error will be suppressed and an empty string will be returned on any failure. For information on constructing Lua patterns, a form of [regular expression], see: * http://www.lua.org/manual/5.1/manual.html#5.4.1 * http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Patterns * http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Ustring_patterns ]] function str.match( frame ) local new_args = str._getParameters( frame.args, {'s', 'pattern', 'start', 'match', 'plain', 'nomatch'} ); local s = new_args['s'] or ''; local start = tonumber( new_args['start'] ) or 1; local plain_flag = str._getBoolean( new_args['plain'] or false ); local pattern = new_args['pattern'] or ''; local match_index = math.floor( tonumber(new_args['match']) or 1 ); local nomatch = new_args['nomatch']; if s == '' then return str._error( 'Пустая строка поиска' ); end if pattern == '' then return str._error( 'Пустой шаблон поиска' ); end if math.abs(start) < 1 or math.abs(start) > mw.ustring.len( s ) then return str._error( 'Индекс начала поиска выходит за допустимые границы' ); end if match_index == 0 then return str._error( 'Индекс совпадения выходит за допустимые границы' ); end if plain_flag then pattern = str._escapePattern( pattern ); end local result if match_index == 1 then -- Find first match is simple case result = mw.ustring.match( s, pattern, start ) else if start > 1 then s = mw.ustring.sub( s, start ); end local iterator = mw.ustring.gmatch(s, pattern); if match_index > 0 then -- Forward search for w in iterator do match_index = match_index - 1; if match_index == 0 then result = w; break; end end else -- Reverse search local result_table = {}; local count = 1; for w in iterator do result_table[count] = w; count = count + 1; end result = result_table[ count + match_index ]; end end if result == nil then if nomatch == nil then return str._error( 'Совпадение не найдено' ); else return nomatch; end else return result; end end --[[ pos This function returns a single character from the target string at position pos. Usage: {{#invoke:String|pos|target_string|index_value}} OR {{#invoke:String|pos|target=target_string|pos=index_value}} Parameters target: The string to search pos: The index for the character to return If invoked using named parameters, Mediawiki will automatically remove any leading or trailing whitespace from the target string. In some circumstances this is desirable, in other cases one may want to preserve the whitespace. The first character has an index value of 1. If one requests a negative value, this function will select a character by counting backwards from the end of the string. In other words pos = -1 is the same as asking for the last character. A requested value of zero, or a value greater than the length of the string returns an error. ]] function str.pos( frame ) local new_args = str._getParameters( frame.args, {'target', 'pos'} ); local target_str = new_args['target'] or ''; local pos = tonumber( new_args['pos'] ) or 0; if pos == 0 or math.abs(pos) > mw.ustring.len( target_str ) then return str._error( 'Значение индекса строки выходит за допустимые границы' ); end return mw.ustring.sub( target_str, pos, pos ); end --[[ str_find This function duplicates the behavior of {{str_find}}, including all of its quirks. This is provided in order to support existing templates, but is NOT RECOMMENDED for new code and templates. New code is recommended to use the "find" function instead. Returns the first index in "source" that is a match to "target". Indexing is 1-based, and the function returns -1 if the "target" string is not present in "source". Important Note: If the "target" string is empty / missing, this function returns a value of "1", which is generally unexpected behavior, and must be accounted for separatetly. ]] function str.str_find( frame ) local new_args = str._getParameters( frame.args, {'source', 'target'} ); local source_str = new_args['source'] or ''; local target_str = new_args['target'] or ''; if target_str == '' then return 1; end local start = mw.ustring.find( source_str, target_str, 1, true ) if start == nil then start = -1 end return start end --[[ find This function allows one to search for a target string or pattern within another string. Usage: {{#invoke:String|find|source_str|target_string|start_index|plain_flag}} OR {{#invoke:String|find|source=source_str|target=target_str|start=start_index|plain=plain_flag}} Parameters source: The string to search target: The string or pattern to find within source start: The index within the source string to start the search, defaults to 1 plain: Boolean flag indicating that target should be understood as plain text and not as a Lua style regular expression, defaults to true If invoked using named parameters, Mediawiki will automatically remove any leading or trailing whitespace from the parameter. In some circumstances this is desirable, in other cases one may want to preserve the whitespace. This function returns the first index >= "start" where "target" can be found within "source". Indices are 1-based. If "target" is not found, then this function returns 0. If either "source" or "target" are missing / empty, this function also returns 0. This function should be safe for UTF-8 strings. ]] function str.find( frame ) local new_args = str._getParameters( frame.args, {'source', 'target', 'start', 'plain' } ); local source_str = new_args['source'] or ''; local pattern = new_args['target'] or ''; local start_pos = tonumber(new_args['start']) or 1; local plain = new_args['plain'] or true; if source_str == '' or pattern == '' then return 0; end plain = str._getBoolean( plain ); local start = mw.ustring.find( source_str, pattern, start_pos, plain ) if start == nil then start = 0 end return start end --[[ replace This function allows one to replace a target string or pattern within another string. Usage: {{#invoke:String|replace|source_str|pattern_string|replace_string|replacement_count|plain_flag}} OR {{#invoke:String|replace|source=source_string|pattern=pattern_string|replace=replace_string| count=replacement_count|plain=plain_flag}} Parameters source: The string to search pattern: The string or pattern to find within source replace: The replacement text count: The number of occurences to replace, defaults to all. plain: Boolean flag indicating that pattern should be understood as plain text and not as a Lua style regular expression, defaults to true ]] function str.replace( frame ) local new_args = str._getParameters( frame.args, {'source', 'pattern', 'replace', 'count', 'plain' } ); local source_str = new_args['source'] or ''; local pattern = new_args['pattern'] or ''; local replace = new_args['replace'] or ''; local count = tonumber( new_args['count'] ); local plain = new_args['plain'] or true; if source_str == '' or pattern == '' then return source_str; end plain = str._getBoolean( plain ); if plain then pattern = str._escapePattern( pattern ); replace = mw.ustring.gsub( replace, "%%", "%%%%" ); --Only need to escape replacement sequences. end local result; if count ~= nil then result = mw.ustring.gsub( source_str, pattern, replace, count ); else result = mw.ustring.gsub( source_str, pattern, replace ); end return result; end --[[ This function adds support for escaping parts of the patterns when using [plain=false]. ]] function str.escape( frame ) local new_args = str._getParameters( frame.args, {'pattern' } ); local pattern = new_args['pattern'] or ''; local result = ''; result = str._escapePattern( pattern ); return result; end --[[ Internal compare string function ]] function str._strcmp(a , b) local s1c = mw.ustring.gcodepoint( a ); local s2c = mw.ustring.gcodepoint( b ); while true do local c1 = s1c(); local c2 = s2c(); if c1 == nil then if c2 == nil then return 0 else return -1 end else if c2 ~= nil then if c1 ~= c2 then return c1 < c2 and -1 or 1 end else return 1 end end end return 0 end --[[ compare This function compare two UTF-8 strings Usage: {{#invoke:String|compare|str1|str2}} Returns: 0 - if strings are equal 1 - if st1 > str2 -1 - if str1 < str2 ]] function str.compare(frame) local str1 = frame.args[1] or ''; local str2 = frame.args[2] or ''; return str._strcmp(str1 , str2) end --[[ simple function to pipe string.rep to templates. ]] function str.rep( frame ) local repetitions = tonumber( frame.args[2] ) if not repetitions then return str._error( 'функция rep ожидает число во втором параметре, а получено "' .. ( frame.args[2] or '' ) .. '"' ) end return string.rep( frame.args[1] or '', repetitions ) end --[[ Helper function that populates the argument list given that user may need to use a mix of named and unnamed parameters. This is relevant because named parameters are not identical to unnamed parameters due to string trimming, and when dealing with strings we sometimes want to either preserve or remove that whitespace depending on the application. ]] function str._getParameters( frame_args, arg_list ) local new_args = {}; local index = 1; local value; for i,arg in ipairs( arg_list ) do value = frame_args[arg] if value == nil then value = frame_args[index]; index = index + 1; end new_args[arg] = value; end return new_args; end --[[ Helper function to handle error messages. ]] function str._error( error_str ) local frame = mw.getCurrentFrame(); local error_category = frame.args.error_category or 'Страницы с ошибками модуля String'; local ignore_errors = frame.args.ignore_errors or false; local no_category = frame.args.no_category or false; if str._getBoolean(ignore_errors) then return ''; end local error_str = '<strong class="error">Ошибка модуля String: ' .. error_str .. '</strong>'; if error_category ~= '' and not str._getBoolean( no_category ) then error_str = '[[Категория:' .. error_category .. ']]' .. error_str; end return error_str; end --[[ Helper Function to interpret boolean strings ]] function str._getBoolean( boolean_str ) local boolean_value; if type( boolean_str ) == 'string' then boolean_str = boolean_str:lower(); if boolean_str == 'false' or boolean_str == 'no' or boolean_str == '0' or boolean_str == '' then boolean_value = false; else boolean_value = true; end elseif type( boolean_str ) == 'boolean' then boolean_value = boolean_str; else error( 'Логическое значение не найдено' ); end return boolean_value end --[[ Helper function that escapes all pattern characters so that they will be treated as plain text. ]] function str._escapePattern( pattern_str ) return mw.ustring.gsub( pattern_str, "([%(%)%.%%%+%-%*%?%[%^%$%]])", "%%%1" ); end return str b4a4e099d7fab23576bae7af327a44c87d13f9cb Модуль:TableTools 828 125 569 292 2021-07-29T21:08:22Z ruwiki>WerySkok 0 1 версия импортирована: Импорт Инфобокса из Русскоязычной википедии. Scribunto text/plain --[[ ------------------------------------------------------------------------------------ -- TableTools -- -- -- -- This module includes a number of functions for dealing with Lua tables. -- -- It is a meta-module, meant to be called from other Lua modules, and should -- -- not be called directly from #invoke. -- ------------------------------------------------------------------------------------ --]] local libraryUtil = require('libraryUtil') local p = {} -- Define often-used variables and functions. local floor = math.floor local infinity = math.huge local checkType = libraryUtil.checkType local checkTypeMulti = libraryUtil.checkTypeMulti --[[ ------------------------------------------------------------------------------------ -- isPositiveInteger -- -- This function returns true if the given value is a positive integer, and false -- if not. Although it doesn't operate on tables, it is included here as it is -- useful for determining whether a given table key is in the array part or the -- hash part of a table. ------------------------------------------------------------------------------------ --]] function p.isPositiveInteger(v) if type(v) == 'number' and v >= 1 and floor(v) == v and v < infinity then return true else return false end end --[[ ------------------------------------------------------------------------------------ -- isNan -- -- This function returns true if the given number is a NaN value, and false -- if not. Although it doesn't operate on tables, it is included here as it is -- useful for determining whether a value can be a valid table key. Lua will -- generate an error if a NaN is used as a table key. ------------------------------------------------------------------------------------ --]] function p.isNan(v) if type(v) == 'number' and tostring(v) == '-nan' then return true else return false end end --[[ ------------------------------------------------------------------------------------ -- shallowClone -- -- This returns a clone of a table. The value returned is a new table, but all -- subtables and functions are shared. Metamethods are respected, but the returned -- table will have no metatable of its own. ------------------------------------------------------------------------------------ --]] function p.shallowClone(t) local ret = {} for k, v in pairs(t) do ret[k] = v end return ret end --[[ ------------------------------------------------------------------------------------ -- removeDuplicates -- -- This removes duplicate values from an array. Non-positive-integer keys are -- ignored. The earliest value is kept, and all subsequent duplicate values are -- removed, but otherwise the array order is unchanged. ------------------------------------------------------------------------------------ --]] function p.removeDuplicates(t) checkType('removeDuplicates', 1, t, 'table') local isNan = p.isNan local ret, exists = {}, {} for i, v in ipairs(t) do if isNan(v) then -- NaNs can't be table keys, and they are also unique, so we don't need to check existence. ret[#ret + 1] = v else if not exists[v] then ret[#ret + 1] = v exists[v] = true end end end return ret end --[[ ------------------------------------------------------------------------------------ -- numKeys -- -- This takes a table and returns an array containing the numbers of any numerical -- keys that have non-nil values, sorted in numerical order. ------------------------------------------------------------------------------------ --]] function p.numKeys(t) checkType('numKeys', 1, t, 'table') local isPositiveInteger = p.isPositiveInteger local nums = {} for k, v in pairs(t) do if isPositiveInteger(k) then nums[#nums + 1] = k end end table.sort(nums) return nums end --[[ ------------------------------------------------------------------------------------ -- affixNums -- -- This takes a table and returns an array containing the numbers of keys with the -- specified prefix and suffix. For example, for the table -- {a1 = 'foo', a3 = 'bar', a6 = 'baz'} and the prefix "a", affixNums will -- return {1, 3, 6}. ------------------------------------------------------------------------------------ --]] function p.affixNums(t, prefix, suffix) checkType('affixNums', 1, t, 'table') checkType('affixNums', 2, prefix, 'string', true) checkType('affixNums', 3, suffix, 'string', true) local function cleanPattern(s) -- Cleans a pattern so that the magic characters ()%.[]*+-?^$ are interpreted literally. s = s:gsub('([%(%)%%%.%[%]%*%+%-%?%^%$])', '%%%1') return s end prefix = prefix or '' suffix = suffix or '' prefix = cleanPattern(prefix) suffix = cleanPattern(suffix) local pattern = '^' .. prefix .. '([1-9]%d*)' .. suffix .. '$' local nums = {} for k, v in pairs(t) do if type(k) == 'string' then local num = mw.ustring.match(k, pattern) if num then nums[#nums + 1] = tonumber(num) end end end table.sort(nums) return nums end --[[ ------------------------------------------------------------------------------------ -- numData -- -- Given a table with keys like ("foo1", "bar1", "foo2", "baz2"), returns a table -- of subtables in the format -- { [1] = {foo = 'text', bar = 'text'}, [2] = {foo = 'text', baz = 'text'} } -- Keys that don't end with an integer are stored in a subtable named "other". -- The compress option compresses the table so that it can be iterated over with -- ipairs. ------------------------------------------------------------------------------------ --]] function p.numData(t, compress) checkType('numData', 1, t, 'table') checkType('numData', 2, compress, 'boolean', true) local ret = {} for k, v in pairs(t) do local prefix, num = mw.ustring.match(tostring(k), '^([^0-9]*)([1-9][0-9]*)$') if num then num = tonumber(num) local subtable = ret[num] or {} if prefix == '' then -- Positional parameters match the blank string; put them at the start of the subtable instead. prefix = 1 end subtable[prefix] = v ret[num] = subtable else local subtable = ret.other or {} subtable[k] = v ret.other = subtable end end if compress then local other = ret.other ret = p.compressSparseArray(ret) ret.other = other end return ret end --[[ ------------------------------------------------------------------------------------ -- compressSparseArray -- -- This takes an array with one or more nil values, and removes the nil values -- while preserving the order, so that the array can be safely traversed with -- ipairs. ------------------------------------------------------------------------------------ --]] function p.compressSparseArray(t) checkType('compressSparseArray', 1, t, 'table') local ret = {} local nums = p.numKeys(t) for _, num in ipairs(nums) do ret[#ret + 1] = t[num] end return ret end --[[ ------------------------------------------------------------------------------------ -- sparseIpairs -- -- This is an iterator for sparse arrays. It can be used like ipairs, but can -- handle nil values. ------------------------------------------------------------------------------------ --]] function p.sparseIpairs(t) checkType('sparseIpairs', 1, t, 'table') local nums = p.numKeys(t) local i = 0 local lim = #nums return function () i = i + 1 if i <= lim then local key = nums[i] return key, t[key] else return nil, nil end end end --[[ ------------------------------------------------------------------------------------ -- size -- -- This returns the size of a key/value pair table. It will also work on arrays, -- but for arrays it is more efficient to use the # operator. ------------------------------------------------------------------------------------ --]] function p.size(t) checkType('size', 1, t, 'table') local i = 0 for k in pairs(t) do i = i + 1 end return i end local function defaultKeySort(item1, item2) -- "number" < "string", so numbers will be sorted before strings. local type1, type2 = type(item1), type(item2) if type1 ~= type2 then return type1 < type2 else -- This will fail with table, boolean, function. return item1 < item2 end end --[[ Returns a list of the keys in a table, sorted using either a default comparison function or a custom keySort function. ]] function p.keysToList(t, keySort, checked) if not checked then checkType('keysToList', 1, t, 'table') checkTypeMulti('keysToList', 2, keySort, { 'function', 'boolean', 'nil' }) end local list = {} local index = 1 for key, value in pairs(t) do list[index] = key index = index + 1 end if keySort ~= false then keySort = type(keySort) == 'function' and keySort or defaultKeySort table.sort(list, keySort) end return list end --[[ Iterates through a table, with the keys sorted using the keysToList function. If there are only numerical keys, sparseIpairs is probably more efficient. ]] function p.sortedPairs(t, keySort) checkType('sortedPairs', 1, t, 'table') checkType('sortedPairs', 2, keySort, 'function', true) local list = p.keysToList(t, keySort, true) local i = 0 return function() i = i + 1 local key = list[i] if key ~= nil then return key, t[key] else return nil, nil end end end --[[ Returns true if all keys in the table are consecutive integers starting at 1. --]] function p.isArray(t) checkType("isArray", 1, t, "table") local i = 0 for k, v in pairs(t) do i = i + 1 if t[i] == nil then return false end end return true end -- { "a", "b", "c" } -> { a = 1, b = 2, c = 3 } function p.invert(array) checkType("invert", 1, array, "table") local map = {} for i, v in ipairs(array) do map[v] = i end return map end --[[ { "a", "b", "c" } -> { ["a"] = true, ["b"] = true, ["c"] = true } --]] function p.listToSet(t) checkType("listToSet", 1, t, "table") local set = {} for _, item in ipairs(t) do set[item] = true end return set end --[[ Recursive deep copy function. Preserves identities of subtables. ]] local function _deepCopy(orig, includeMetatable, already_seen) -- Stores copies of tables indexed by the original table. already_seen = already_seen or {} local copy = already_seen[orig] if copy ~= nil then return copy end if type(orig) == 'table' then copy = {} for orig_key, orig_value in pairs(orig) do copy[deepcopy(orig_key, includeMetatable, already_seen)] = deepcopy(orig_value, includeMetatable, already_seen) end already_seen[orig] = copy if includeMetatable then local mt = getmetatable(orig) if mt ~= nil then local mt_copy = deepcopy(mt, includeMetatable, already_seen) setmetatable(copy, mt_copy) already_seen[mt] = mt_copy end end else -- number, string, boolean, etc copy = orig end return copy end function p.deepCopy(orig, noMetatable, already_seen) checkType("deepCopy", 3, already_seen, "table", true) return _deepCopy(orig, not noMetatable, already_seen) end --[[ Concatenates all values in the table that are indexed by a number, in order. sparseConcat{ a, nil, c, d } => "acd" sparseConcat{ nil, b, c, d } => "bcd" ]] function p.sparseConcat(t, sep, i, j) local list = {} local list_i = 0 for _, v in p.sparseIpairs(t) do list_i = list_i + 1 list[list_i] = v end return table.concat(list, sep, i, j) end --[[ -- This returns the length of a table, or the first integer key n counting from -- 1 such that t[n + 1] is nil. It is similar to the operator #, but may return -- a different value when there are gaps in the array portion of the table. -- Intended to be used on data loaded with mw.loadData. For other tables, use #. -- Note: #frame.args in frame object always be set to 0, regardless of -- the number of unnamed template parameters, so use this function for -- frame.args. --]] function p.length(t) local i = 1 while t[i] ~= nil do i = i + 1 end return i - 1 end function p.inArray(arr, valueToFind) checkType("inArray", 1, arr, "table") -- if valueToFind is nil, error? for _, v in ipairs(arr) do if v == valueToFind then return true end end return false end return p fe918509f168332267834b3a6f5c219a9de5b2e7 Модуль:Template call code 828 126 571 2021-07-29T21:08:22Z ruwiki>WerySkok 0 1 версия импортирована: Импорт Инфобокса из Русскоязычной википедии. Scribunto text/plain local getArgs = require('Module:Arguments').getArgs local ru = mw.language.new('ru') local p = {} -- Используется для того, чтобы можно было удалять элементы из таблицы local function copy(other) local res = {} for k, v in pairs(other) do res[k] = v end return res end local function makeInvokeFunc(funcName) return function (frame) local args = copy(getArgs(frame, { trim = false, removeBlanks = false })) return p[funcName](args) end end p.withoutParams = makeInvokeFunc('_withoutParams') function p._withoutParams(args) local name = args[1] table.remove(args, 1) -- Вещи типа «=» в первом параметре if not name then for k, v in pairs(args) do if not k:find('^_') then name = k .. '=' .. v args[k] = nil break end end end local flags = {} for i, v in ipairs(args) do if v == 'nl' or v == 'nolink' then flags.noLink = true elseif v == 's' then flags.subst = true elseif v == 'п' then flags.podst = true elseif v == 'g' then flags.global = true elseif v == 'nav' then flags.nav = true elseif v == 'noredir' then flags.noRedirect = true elseif v == 'u' then flags.ucFirst = true elseif v == 'b' then flags.black = true end end if name then local trimmedName = mw.text.trim(name) if ru:lc(mw.ustring.sub(trimmedName, 1, 6)) == 'subst:' then flags.subst = true name = mw.ustring.sub(trimmedName, 7) end if ru:lc(mw.ustring.sub(trimmedName, 1, 6)) == 'подст:' then flags.podst = true name = mw.ustring.sub(trimmedName, 7) end end if args.text == '' then args.text = nil end if args.comment == '' then args.comment = nil end if args.lang == '' then args.lang = nil end if args.sister == '' then args.sister = nil end local currentTitle = mw.title.getCurrentTitle() -- При опущенном первом параметре берём имя шаблона из названия страницы if name == '' or not name then local currentTitleRoot = currentTitle.rootText if not flags.ucFirst and ((ru:uc(currentTitleRoot) ~= currentTitleRoot and -- Книга:Литературное наследство, TranslateDate not mw.ustring.match(currentTitleRoot, '^[А-Яа-яA-Za-z]+:?[А-ЯA-Z]') ) or #currentTitleRoot == 1 ) then name = ru:lcfirst(currentTitleRoot) else name = currentTitleRoot end end local global = flags.global or mw.ustring.sub(name, 1, 1) == ':' -- Начинаем собирать код local linkBody, titleObject, linkBegin, linkDivider, linkEnd local prefixes = {} if args.lang then table.insert(prefixes, args.lang) end if args.sister then table.insert(prefixes, args.sister) end linkBody = table.concat(prefixes, ':') if #linkBody ~= 0 then linkBody = ':' .. linkBody end if mw.ustring.sub(name, 1, 1) ~= ':' then linkBody = linkBody .. ':' end if not global then linkBody = linkBody .. 'Template:' end linkBody = linkBody .. name titleObject = mw.title.new(linkBody) local noLink = flags.noLink or currentTitle == titleObject local takeBracketsInLink = not noLink and mw.ustring.len(name) == 1 and not flags.black and not flags.subst and not flags.podst if not noLink then if not flags.noRedirect or ( flags.noRedirect and not args.lang and not args.sister and not titleObject.exists ) then linkBegin = '[[' linkEnd = ']]' linkDivider = '|' else linkBegin = '[' linkEnd = ']' linkDivider = ' ' linkBody = titleObject:fullUrl('redirect=no') end end local text = '' if flags.nav and currentTitle == titleObject then text = text .. '\'\'\'' end if not flags.black then text = text .. '<span class="wp-templatelink">' end text = text .. '{' if not takeBracketsInLink then text = text .. '{' end if flags.subst then text = text .. 'subst:' elseif flags.podst then text = text .. 'подст:' end if not flags.black then text = text .. '</span>' end text = text .. '<span data-navboxnavigation-link="0">' local commentedLabel if args.comment then -- https://phabricator.wikimedia.org/T200704 -- commentedLabel = mw.getCurrentFrame():expandTemplate({title = 'comment', args = {(args.text or name), args.comment}}) commentedLabel = '<span class="commentedText" title="' .. args.comment .. '" style="border-bottom: 1px dotted; cursor: help;">' .. (args.text or name) .. '</span>' end local label = (commentedLabel or args.text or name) if not noLink then if flags.noRedirect then text = text .. '<span class="plainlinks">' end text = text .. linkBegin .. linkBody .. linkDivider if not noLink and takeBracketsInLink then text = text .. '<span class="wp-templatelink">{</span>' end text = text .. label if not noLink and takeBracketsInLink then text = text .. '<span class="wp-templatelink">}</span>' end text = text .. linkEnd if flags.noRedirect then text = text .. '</span>' end else text = text .. label end text = text .. '</span>' if not flags.black then text = text .. '<span class="wp-templatelink">' end text = text .. '}' if not takeBracketsInLink then text = text .. '}' end if not flags.black then text = text .. '</span>' end if flags.nav and currentTitle == titleObject then text = text .. '\'\'\'' end return text end function addParams(args, params) local text, equals_pos, param, value = '', 0, '', '' function addPipe() if params.spaced then text = text .. ' ' end text = text .. '<span' if not params.black then text = text .. ' class="wp-templatelink"' end if not params.spaced then text = text .. ' style="margin:0 2px;"' end text = text .. '>&#124;</span>' end for k, v in pairs(args) do if type(k) == 'number' then -- Неименованные параметры equals_pos = v:find('=') if equals_pos and v:find('{{=}}') == equals_pos - 2 then equals_pos = nil end if equals_pos then -- Содержащие «=» преобразуем в именованные param = v:sub(1, equals_pos - 1) value = v:sub(equals_pos + 1) addPipe() text = text .. param .. '=' .. value else -- Истинно неименованные addPipe() text = text .. v end elseif not k:find('^_') then -- Именованные параметры, исключая модификаторы внешнего вида addPipe() text = text .. k .. '=' .. v end end return text end p.withParams = makeInvokeFunc('_withParams') function p._withParams(args) local name = args[1] table.remove(args, 1) -- Вещи типа «=» в первом параметре if not name then for k, v in pairs(args) do if not k:find('^_') then name = k .. '=' .. v args[k] = nil break end end end local optpText if name then local spanOffset = mw.ustring.find(name, '<span') -- След использования шаблона optp if spanOffset then optpText = mw.ustring.sub(name, spanOffset) name = mw.ustring.sub(name, 1, spanOffset - 1) end end local yesno = require('Module:Yesno') local nobr = yesno(args._nobr, false) local tag = args._tag or 'span' local style = args._style local spaced = yesno(args._spaced, false) local subst = yesno(args._s, false) local podst = yesno(args['_п'], false) local global = yesno(args._g, false) or name and mw.ustring.sub(name, 1, 1) == ':' local lang = args._lang local sister = args._sister local nav = yesno(args._nav, false) local ucFirst = yesno(args._u, false) local black = yesno(args._b, false) or tag ~= 'span' local noLink = yesno(args._nolink or args._nl, false) or not yesno(args._link, false) local textInPlaceOfName = args._text local comment = args._comment local noRedirect = yesno(args._noredir, false) local prefix = args._prefix local postfix = args._postfix if textInPlaceOfName == '' then textInPlaceOfName = nil end if comment == '' then comment = nil end if lang == '' then lang = nil end if sister == '' then sister = nil end if name then local trimmedName = mw.text.trim(name) if ru:lc(mw.ustring.sub(trimmedName, 1, 6)) == 'subst:' then subst = true name = mw.ustring.sub(trimmedName, 7) end if ru:lc(mw.ustring.sub(trimmedName, 1, 6)) == 'подст:' then podst = true name = mw.ustring.sub(trimmedName, 7) end end local currentTitle = mw.title.getCurrentTitle() -- При опущенном первом параметре берём имя шаблона из названия страницы if name == '' or not name then local currentTitleRoot = currentTitle.rootText if not ucFirst and ((ru:uc(currentTitleRoot) ~= currentTitleRoot and -- Книга:Литературное наследство, TranslateDate not mw.ustring.match(currentTitleRoot, '^[А-Яа-яA-Za-z]+:?[А-ЯA-Z]') ) or #currentTitleRoot == 1 ) then name = ru:lcfirst(currentTitleRoot) else name = currentTitleRoot end end -- Начинаем собирать код local linkBody, titleObject, linkBegin, linkDivider, linkEnd local prefixes = {} if lang then table.insert(prefixes, lang) end if sister then table.insert(prefixes, sister) end linkBody = table.concat(prefixes, ':') if #linkBody ~= 0 then linkBody = ':' .. linkBody end if mw.ustring.sub(name, 1, 1) ~= ':' then linkBody = linkBody .. ':' end if not global then linkBody = linkBody .. 'Template:' end linkBody = linkBody .. name titleObject = mw.title.new(linkBody) local noLink = noLink or currentTitle == titleObject local takeBracketsInLink = not noLink and mw.ustring.len(name) == 1 and not black and not subst and not podst if not noLink then if not noRedirect or ( noRedirect and not lang and not sister and not titleObject.exists ) then linkBegin = '[[' linkEnd = ']]' linkDivider = '|' else linkBegin = '[' linkEnd = ']' linkDivider = ' ' linkBody = titleObject:fullUrl('redirect=no') end end local text = '' if tag then text = text .. '<' .. tag .. ' class="templateCallCode' if nobr then text = text .. ' nowrap' end text = text .. '"' if style then text = text .. ' style="' .. style .. '"' end text = text .. '>' end if prefix then text = text .. prefix end if not black then text = text .. '<span class="wp-templatelink">' end text = text .. '{{' if subst then text = text .. 'subst:' elseif podst then text = text .. 'подст:' end if not black then text = text .. '</span>' end if nav and currentTitle == titleObject then text = text .. '\'\'\'' end local commentedLabel if comment then -- https://phabricator.wikimedia.org/T200704 -- commentedLabel = mw.getCurrentFrame():expandTemplate({title = 'comment', args = {(text or name), comment}}) commentedLabel = '<span class="commentedText" title="' .. comment .. '" style="border-bottom: 1px dotted; cursor: help;">' .. (textInPlaceOfName or name) .. '</span>' end local label = (commentedLabel or textInPlaceOfName or name) if not noLink then if noRedirect then text = text .. '<span class="plainlinks">' end text = text .. linkBegin .. linkBody .. linkDivider .. label .. linkEnd if noRedirect then text = text .. '</span>' end else text = text .. label end if nav and currentTitle == titleObject then text = text .. '\'\'\'' end if optpText then text = text .. optpText end text = text .. addParams(args, { spaced = spaced, black = black, }) if spaced then text = text .. ' ' end if not black then text = text .. '<span class="wp-templatelink">' end text = text .. '}}' if not black then text = text .. '</span>' end if postfix then text = text .. postfix end if tag then text = text .. '</' .. tag .. '>' end return text end p.onlyParams = makeInvokeFunc('_onlyParams') function p._onlyParams(args) local span = mw.html.create('span') span:css( 'color', mw.getCurrentFrame():expandTemplate({ title = 'optp/color' }) ) local yesno = require('Module:Yesno') span:wikitext(addParams(args, { spaced = yesno(args._spaced, false), black = true, })) return tostring(span) end return p 0b9f3af403c5d8136788ce6aae12a9b96ee4fe52 Модуль:Yesno 828 127 573 2021-07-29T21:08:23Z ruwiki>WerySkok 0 1 версия импортирована: Импорт Инфобокса из Русскоязычной википедии. Scribunto text/plain -- Function allowing for consistent treatment of boolean-like wikitext input. -- It works similarly to the template {{yesno}}. return function (val, default) -- If your wiki uses non-ascii characters for any of "yes", "no", etc., you -- should replace "val:lower()" with "mw.ustring.lower(val)" in the -- following line. val = type(val) == 'string' and val:lower() or val if val == nil then return nil elseif val == true or val == 'yes' or val == 'y' or val == 'true' or val == 't' or val == 'да' or val == 'д' or val == '+' or tonumber(val) == 1 then return true elseif val == false or val == 'no' or val == 'n' or val == 'false' or val == 'f' or val == 'нет' or val == 'н' or val == '-' or tonumber(val) == 0 then return false else return default end end 2aa6facc3ee47eb7582d828363d3c1ddc64593d2 Модуль:Transclude 828 144 657 330 2021-07-29T21:08:23Z ruwiki>WerySkok 0 1 версия импортирована: Импорт Инфобокса из Русскоязычной википедии. Scribunto text/plain local p={} -- Вызывает внутренний шаблон с аргументами объемлющего шаблона function p.call(frame) local template = frame.args[1] local args = frame:getParent().args return frame:expandTemplate{ title=template, args=args } end -- Общая реализация для forall и call local function forallImpl(args, separator, conjunction, func) -- нумерованные ключи из args local keys = {} -- перебор в произвольном порядке, даже для нумерованных ключей for key, value in pairs(args) do if type(key) == 'number' and value and value ~= '' then table.insert(keys, key) end end table.sort(keys) local results = {} for _, key in ipairs(keys) do local value = func(args[key]) table.insert(results, value) end return mw.text.listToText(results, separator, conjunction) end -- Вызывает внутренний шаблон, передавая ему нумерованные параметры объемлющего шаблона по-одному function p.forall(frame) local template = frame.args[1] local separator = frame.args.separator or '' local conjunction = frame.args.conjunction or separator local args = frame:getParent().args local func = function(value) return frame:expandTemplate{ title = template, args = {value} } -- или другой frame? end return forallImpl(args, separator, conjunction, func) end -- Берёт нумерованные аргументы объемлющего шаблона и склеивает их в единую строку function p.join(frame) local separator = frame.args[1] or '' local conjunction = frame.args[2] or separator local args = frame:getParent().args local func = function(value) return value end return forallImpl(args, separator, conjunction, func) end -- Служебная функция: удаляет дубликаты из отсортированного массива с нумерованными индексами local function deleteDuplicates(args) local res = {} for key, value in pairs(args) do if args[key+1] ~= value then table.insert(res, value) end end return res end -- Вызывает внутренний шаблон несколько раз, передавая в него блоки аргументов объемлющего шаблона function p.npc(frame) local args = frame:getParent().args local templateFrame = frame:getParent() local template = frame.args[1] -- определение, блоки аргументов с какими номерами нужны: -- если в объемлющем шаблоне есть "параметр12" и в вызове модуля есть "параметр", то вызывается 12-й блок local nums = {} for key, _ in pairs(args) do local main, num = string.match(key, '^(.-)%s*(%d*)$') num = tonumber(num) -- учитывать "параметр12", только если задано "параметр" if num and frame.args[main] then table.insert(nums, num) end end table.sort(nums) nums = deleteDuplicates(nums) -- проходить по нужным номерам блоков по возрастанию и однократно -- подставлять в шаблон: -- 1. общие аргументы данного модуля -- 2. аргументы объемлющего шаблона вида "параметр12" как "параметр" в 12-й блок local results = {} for _, blockNum in ipairs(nums) do -- общие аргументы модуля, которые передаются в каждый блок local blockArgs = mw.clone(frame.args) -- metatable ломает expandTemplate setmetatable(blockArgs, nil) for key, value in pairs(args) do local main, num = string.match(key, '^(.-)%s*(%d*)$') num = tonumber(num) -- передавать "параметр12" как "параметр" в 12-й блок, только если есть "параметр" в вызове модуля if blockNum == num and frame.args[main] then blockArgs[main] = value end end local blockText = templateFrame:expandTemplate{ title=template; args=blockArgs } table.insert(results, blockText) end return table.concat(results) end -- Действует аналогично forall по числовой переменной, изменяющейся (по умолчанию, от 1) до f.args[2]. function p.cycle(f) local tf,ac,op=f:getParent(), {}, f.args.output or 'inline'; local sep=''; if op == 'newline' then sep='\n'; end for p,k in pairs(f.args) do if type(p)=='number' then if p>2 then ac[p-1]=k end else ac[p]=k end end local s,fh = f.args[2]:match('^%s*(%-?%d+)%s*%.%.') or 1, f.args[2]:match('%.%.%s*(%S.*)%s*$') or f.args[2] or ''; fh=tonumber(fh) or fh:match('^%s*(.-)%s*$'); s=tonumber(s); local acr={}; if not s then error('Начало цикла «'..s..'» — не число') end local function dc(order) local r=tf:expandTemplate{ title=f.args[1]; args={s,unpack(ac)} } if order == 'desc' then s=s-1; else s=s+1; end if r~='' then table.insert(acr,r); return r end end if type(fh)=='number' then if fh > s then while s<=fh do dc('asc') end else while s>=fh do dc('desc') end end elseif fh~='' then while tf:expandTemplate{ title=fh; args={s,unpack(ac)} } do dc('asc') end else while dc('asc') do end end return table.concat(acr, sep) end return p c17cfab4cebc23157f5ab8d18c7e4f5c273bfa59 Модуль:Якорь 828 237 575 2021-07-29T21:08:24Z ruwiki>WerySkok 0 1 версия импортирована: Импорт Инфобокса из Русскоязычной википедии. Scribunto text/plain local getArgs = require('Module:Arguments').getArgs local yesno = require('Module:Yesno') local compressSparseArray = require('Module:TableTools').compressSparseArray local p = {} local function add_anchor(anchor, text, visible) local result = mw.html.create('span') :attr('id', anchor) :wikitext(text) if visible then result:addClass('highlight-target') end return tostring(result) end local function unpack(...) local frame = ... local args if type(frame.args) == 'table' then args = getArgs(frame) elseif type(frame) == 'table' then args = frame else args = {...} end return args end function p.main(...) local args = unpack(...) local anchors = compressSparseArray(args) local text local visible = yesno(args.visible or args.v) if visible then text = args.text or args['текст'] or args[1] end local result = text for i, v in ipairs(anchors) do result = add_anchor(anchors[i], result, visible) --[[ создание старого вида якорей для совместимости, см. Обсуждение шаблона:Якорь#Новые html5 ссылки и старые ]] local encoded_anchor = mw.uri.encode(anchors[i], 'WIKI'):gsub('%%', '.') if anchors[i] ~= encoded_anchor then result = add_anchor(encoded_anchor, result, visible) end end return result end return p 2cd9bcc85d4af30c1681bbadfc7d10c60a63e5f2 Шаблон:Указание авторства русскоязычной Википедии 10 235 559 2021-07-30T08:31:06Z ruwiki>WerySkok 0 Новая страница: «<includeonly>{| style="border: 1px solid #e0e0e0; background-color: #f8f8f8; color:black; margin: 5px auto; width: 60%;" |- | style="padding: 3px 10px;" | File:...» wikitext text/x-wiki <includeonly>{| style="border: 1px solid #e0e0e0; background-color: #f8f8f8; color:black; margin: 5px auto; width: 60%;" |- | style="padding: 3px 10px;" | [[File:Wikipedia-logo-v2.svg|30px|Wikipedia logo]] | style="font-size: 90%; padding: 3px;" |{{Namespace detect|template=Данный шаблон|other=Данная страница}} использует материал из {{Namespace detect|template=шаблона|other=страницы}} [[w:ru:{{{1|{{FULLPAGENAME}}}}}|{{{1|{{FULLPAGENAME}}}}}]] с русскоязычной Википедии, который выпущен под [[w:ru:Википедия:Текст лицензии Creative Commons Attribution-ShareAlike 3.0 Unported|лицензией Creative Commons Attribution-ShareAlike 3.0 Unported]] ([https://ru.wikipedia.org/w/index.php?title={{urlencode:{{{1|{{FULLPAGENAME}}}}}}}&action=history посмотреть авторов]). |} [[Категория:{{Namespace detect|main=Статьи|category=Категории|file=Файлы|template=Шаблоны|other=Страницы}} из русскоязычной Википедии‎]]</includeonly> <noinclude> {{Doc}} [[Категория:Шаблоны с указанием авторства]] {{Указание авторства англоязычной Википедии|Template:En-WP attribution notice}} </noinclude> f6a3b5534c9f0bd71170f01c372f6d47cc03c302 Шаблон:Документировать 10 18 635 2021-07-30T08:33:09Z ruwiki>WerySkok 0 wikitext text/x-wiki {{ombox |type = content |text = '''Этому {{#ifeq: {{NAMESPACE}} | Модуль | модулю | шаблону }} не хватает документации.''' |text-small = Вы можете помочь проекту, {{big|'''[[{{SUBJECTSPACE}}:{{PAGENAME:{{{1|{{SUBJECTPAGENAME}}/doc}}}}}|сделав описание {{#ifeq: {{NAMESPACE}} | Модуль | модуля | шаблона }}]]'''}}: что он делает, как его использовать, какие параметры он принимает, в какие категории добавляет. Это поможет другим использовать его. * Не забывайте про категории ({{#ifeq: {{NAMESPACE}} | Модуль || на странице /doc&#32; }}их нужно оборачивать в {{tag|includeonly}}) и [[вп:ВП:Интервики|интервики]]. * Некоторые советы по оформлению есть на Википедии на странице проекта «[[вп:Проект:Технические работы/Шаблоны/Документирование|Документирование шаблонов]]». }}<includeonly>{{#if: {{{nocat|}}}{{#ifeq: {{PAGENAME}} | {{SUBPAGENAME}} || {{#ifeq: {{SUBPAGENAME}} | песочница | nocat }} }} || {{#switch: {{NAMESPACE}} | {{ns:10}} = [[Категория:Шаблоны:Недокументированные]] | {{ns:828}} = {{#ifeq:{{ROOTPAGENAME}}|Песочница||[[Категория:Модули:Недокументированные]]}} }} }}</includeonly><noinclude> {{doc-inline}} Данное сообщение появляется при отсутствующей странице документации, включаемой шаблоном {{t|doc}}. {{doc-end}} {{Указание авторства русскоязычной Википедии}} [[Категория:Шаблоны:Предупреждения]] [[Категория:Шаблоны:Для документирования шаблонов]] </noinclude> 2de13a375cc1c8a836791cda48d72fe9d8b3a1f4 Модуль:Infobox 828 211 470 2021-08-16T20:12:46Z ruwiki>Putnik 0 scope="colgroup" для заголовков Scribunto text/plain local p = {}; local yesno = require('Module:Yesno') local function _renderLine( frame, args, i ) if args[ 'заголовок' .. i ] and args[ 'заголовок' .. i ] == '-' then return '' elseif args[ 'заголовок' .. i ] and args[ 'заголовок' .. i ] ~= '' then local style = ( args[ 'стиль_заголовков' ] or '' ) .. ( args[ 'стиль_заголовка' .. i ] or '' ); local class = ( args[ 'класс' .. i ] or '' ); return '\n<tr>\n<th colspan="2" scope="colgroup" class="infobox-header ' .. class .. '" style="' .. style .. '">' .. args[ 'заголовок' .. i ] .. '</th>\n</tr>'; end if args[ 'блок' .. i ] and args[ 'блок' .. i ] ~= '' then return args[ 'блок' .. i ]; end local text = args[ 'текст' .. i ] or ''; if args[ 'викиданные' .. i ] and args[ 'викиданные' .. i ] ~= '' then text = frame:expandTemplate{ title = 'Wikidata', args = { args[ 'викиданные' .. i ], text, from = args[ 'from' ] or '' } }; end if text ~= '' then local label = args[ 'метка' .. i ] or ''; local class = args[ 'класс' .. i ] or ''; if string.find(class, 'noplainlist') == nil and string.find(class, 'nofirstlevel') == nil then class = class .. ' plainlist'; end if class ~= '' then class = ' class="' .. class .. '"'; end local style = ( args[ 'стиль_текстов' ] or '' ) .. ( args[ 'стиль_текста' ] or '' ) .. ( args[ 'стиль_текста' .. i ] or '' ); if label == '' then style = 'text-align:center;' .. style; end if style ~= '' then style = ' style="' .. style .. '"'; end if label ~= '' then local labelClass = args[ 'класс_меток' ] or ''; if string.find(labelClass, 'noplainlist') == nil and string.find(labelClass, 'nofirstlevel') == nil then labelClass = labelClass .. ' plainlist'; end if labelClass ~= '' then labelClass = ' class="' .. labelClass .. '"'; end local labelStyle = ( args[ 'стиль_меток' ] or '' ) .. ( args[ 'стиль_метки' .. i ] or '' ); if labelStyle ~= '' then labelStyle = ' style="' .. labelStyle .. '"'; end return '\n<tr>\n<th scope="row"' .. labelClass .. labelStyle .. '>' .. label .. '</th>' .. '\n<td' .. class .. style .. '>\n' .. text .. '</td>\n</tr>'; end return '\n<tr>\n<td colspan="2"' .. class .. style .. '>\n' .. text .. '</td>\n</tr>'; end return ''; end local function maxNumber ( args ) local maxNumber = 0 for argName, _ in pairs(args) do local argNumber = mw.ustring.match(argName, '^[^0-9]+([0-9]+)$') if argNumber and tonumber(argNumber) > maxNumber then maxNumber = tonumber(argNumber) end end return maxNumber end function p.renderLine( frame ) local args = frame:getParent().args; return _renderLine(frame, args, '') end function p.renderLines( frame ) local args = frame:getParent().args; local res = '' local header, text = '', '' local autoHeaders = yesno(args [ 'автозаголовки' ] or 'false', false) for i = 1, maxNumber(args) do if args[ 'заголовок' .. i ] and args[ 'заголовок' .. i ] ~= '' then if text ~= '' or not autoHeaders then res = res .. header .. text end header, text = _renderLine(frame, args, i), '' else text = text .. _renderLine(frame, args, i) end end if text ~= '' or not autoHeaders then res = res .. header .. text end return res end return p; c830c997bd3d15923f347277e3b0ae71b7ba917e 637 470 2021-08-30T20:11:48Z ruwiki>WerySkok 0 1 версия импортирована Scribunto text/plain local p = {}; local yesno = require('Module:Yesno') local function _renderLine( frame, args, i ) if args[ 'заголовок' .. i ] and args[ 'заголовок' .. i ] == '-' then return '' elseif args[ 'заголовок' .. i ] and args[ 'заголовок' .. i ] ~= '' then local style = ( args[ 'стиль_заголовков' ] or '' ) .. ( args[ 'стиль_заголовка' .. i ] or '' ); local class = ( args[ 'класс' .. i ] or '' ); return '\n<tr>\n<th colspan="2" scope="colgroup" class="infobox-header ' .. class .. '" style="' .. style .. '">' .. args[ 'заголовок' .. i ] .. '</th>\n</tr>'; end if args[ 'блок' .. i ] and args[ 'блок' .. i ] ~= '' then return args[ 'блок' .. i ]; end local text = args[ 'текст' .. i ] or ''; if args[ 'викиданные' .. i ] and args[ 'викиданные' .. i ] ~= '' then text = frame:expandTemplate{ title = 'Wikidata', args = { args[ 'викиданные' .. i ], text, from = args[ 'from' ] or '' } }; end if text ~= '' then local label = args[ 'метка' .. i ] or ''; local class = args[ 'класс' .. i ] or ''; if string.find(class, 'noplainlist') == nil and string.find(class, 'nofirstlevel') == nil then class = class .. ' plainlist'; end if class ~= '' then class = ' class="' .. class .. '"'; end local style = ( args[ 'стиль_текстов' ] or '' ) .. ( args[ 'стиль_текста' ] or '' ) .. ( args[ 'стиль_текста' .. i ] or '' ); if label == '' then style = 'text-align:center;' .. style; end if style ~= '' then style = ' style="' .. style .. '"'; end if label ~= '' then local labelClass = args[ 'класс_меток' ] or ''; if string.find(labelClass, 'noplainlist') == nil and string.find(labelClass, 'nofirstlevel') == nil then labelClass = labelClass .. ' plainlist'; end if labelClass ~= '' then labelClass = ' class="' .. labelClass .. '"'; end local labelStyle = ( args[ 'стиль_меток' ] or '' ) .. ( args[ 'стиль_метки' .. i ] or '' ); if labelStyle ~= '' then labelStyle = ' style="' .. labelStyle .. '"'; end return '\n<tr>\n<th scope="row"' .. labelClass .. labelStyle .. '>' .. label .. '</th>' .. '\n<td' .. class .. style .. '>\n' .. text .. '</td>\n</tr>'; end return '\n<tr>\n<td colspan="2"' .. class .. style .. '>\n' .. text .. '</td>\n</tr>'; end return ''; end local function maxNumber ( args ) local maxNumber = 0 for argName, _ in pairs(args) do local argNumber = mw.ustring.match(argName, '^[^0-9]+([0-9]+)$') if argNumber and tonumber(argNumber) > maxNumber then maxNumber = tonumber(argNumber) end end return maxNumber end function p.renderLine( frame ) local args = frame:getParent().args; return _renderLine(frame, args, '') end function p.renderLines( frame ) local args = frame:getParent().args; local res = '' local header, text = '', '' local autoHeaders = yesno(args [ 'автозаголовки' ] or 'false', false) for i = 1, maxNumber(args) do if args[ 'заголовок' .. i ] and args[ 'заголовок' .. i ] ~= '' then if text ~= '' or not autoHeaders then res = res .. header .. text end header, text = _renderLine(frame, args, i), '' else text = text .. _renderLine(frame, args, i) end end if text ~= '' or not autoHeaders then res = res .. header .. text end return res end return p; c830c997bd3d15923f347277e3b0ae71b7ba917e Шаблон:Карточка/doc 10 226 645 2021-08-30T19:19:07Z ruwiki>WerySkok 0 wikitext text/x-wiki {{docpage}} {{OnLua|Infobox|renderLines}} Это меташаблон для создания [[вп:Википедия:Шаблоны-карточки|шаблонов-карточек]]. == Параметры == === Служебные === ; имя: Имя шаблона, необходимое для корректной работы служебных инструментов на всех страницах, где используется шаблон. Для простоты можно использовать <code><nowiki>{{subst:PAGENAME}}</nowiki></code>. ; автозаголовки: Указание «да» приводит к автоматическому скрытию заголовков, после которых, вплоть до следующего заголовка, все поля пусты. Возможно использовать фиктивные заголовки «-» для прерывания области скрытия. Будет работать некорректно, если требуется указать два заголовка подряд — например, при использовании многоуровневых заголовков. В этом случае рекомендуется явно указать «нет» на случай смены значения по умолчанию с «нет» на «да». ; from: Указывается элемент Викиданных, из которого берётся информация. === Основные === ; вверху: Текст, отображаемый вверху таблицы. Обычно это название предмета статьи. ; вверху2: Дополнительный текст, отображаемый вверху таблицы. Обычно используется для оригинального названия. ; вверху3: Дополнительный текст, отображаемый вверху таблицы. ; изображение: Изображение, которое будет отображено под основным заголовком в правой части таблицы (правее заголовков/списков). Параметр ''изображение'' допускает стандартный викикод для отображения. Для разных типов параметра можно использовать {{tl|Форматирование изображения}}. Обычно предпочтительнее использовать код <code><nowiki>{{Карточка/изображение|{{{изображение|}}}|size={{{ширина|}}}|caption={{{описание изображения|}}}}}</nowiki></code>. ; подпись: Подпись под изображением. Отображается только в том случае, если задано изображение. При использовании {{tlp|Карточка/изображение}} не заполняется. ; изображение2: Дополнительное изображение. ; изображение3: Дополнительное изображение. ; заголовок<sub>n</sub>: Используется для создания заголовков в ряду. Этот и следующие 2 параметра работают при n≥1. ; метка<sub>n</sub>: Используется для подписи текста ; текст<sub>n</sub>: Используется для принятия параметров в специализированных шаблонах-карточках. ; блок<sub>n</sub>: Технический параметр, используется для вставки блоков, заключённых в &lt;tr&rt;, таких как {{t|карточка/блок}}. ; внизу ; внизу<sub>n</sub>: Ячейка во всю ширину таблицы, располагающаяся внизу тела шаблона (то есть под заголовками/метками и текстом). === Стили === ; стиль_тела: Применяется ко всей карточке, обычно используется для указания её ширины, например, <code>width:23em;</code> ; стиль_вверху: Применяется к полю «вверху», например, для указания цвета фона или изменения размера шрифта: <code>font-size:medium;</code> ; стиль_вверху<sub>n</sub>: Используется для изменения стиля дополнительного текста вверху таблицы, например, чтобы убрать курсивное начертание: <code>font-style:normal;</code> ; стиль_изображения: Применяется к ячейке, в которой располагается изображение и его описание ; стиль_изображения<sub>n</sub>: Применяется к ячейке, в которой располагается дополнительное изображение ; стиль_подписи: Применяется к подписи изображения ; стиль_заголовков: С помощью этого стиля можно настроить отображение заголовков, в частности, указать цвет фона: <code>background: #a3eea3;</code> ; стиль_заголовка<sub>n</sub>: Применяется к конкретному заголовку в строке n ; стиль_меток: Применяется к меткам ; стиль_метки<sub>n</sub>: Применяется к конкретной метке в строке n ; стиль_текста: Применяется к тексту ; стиль_текста<sub>n</sub>: Применяется к конкретному тексту в строке n ; стиль_внизу: Эти стили применяются не только в первому ''внизу'', но и ко всем остальным — в отличие от ''стиль_вверху''. ; стиль_внизу<sub>n</sub>: CSS-стили, которые должны быть применены к нижним (указанными параметрами ''внизу'' и ''внизу<sub>n</sub>'') ячейкам. == Возможности == === Сдвоенные ячейки === Если для параметра <code>текст<sub>n</sub></code> значение <code>метка<sub>n</sub></code> не определено, то <code>текст<sub>n</sub></code> автоматически расширяется до 2 ячеек. Для выравнивания по левой стороне можно использовать следующий код: <pre><nowiki> |текст2 = {{{параметр|}}} |стиль_текста2 = text-align:left; </nowiki></pre> === Необязательные ячейки === Ряд с меткой, но без текста не будет отображён. Это позволяет легко создавать необязательные параметры в специализированных шаблонах-карточках. Для создания опциональной ячейки используйте параметр следующим образом: <pre><nowiki> |метка5 = Население |текст5 = {{{население|}}} </nowiki></pre> Таким образом, если параметр <code>население</code> не будет определён, строка «Население» не будет отображена. === Необязательные заголовки === Таким же образом можно организовать необязательные заголовки. Следующий пример будет выводить заголовок «Структура», если параметры <code>содержимое</code> и <code>размещение</code> определены: <pre><nowiki> |заголовок5 = {{#if:{{{содержимое|}}}{{{размещение|}}}|Структура}} |метка6 = Содержимое |текст6 = {{{содержимое|}}} |метка7 = Размещение |текст7 = {{{размещение|}}} </nowiki></pre> Если есть заголовокN, то текстN и меткаN игнорируются. Если нет заданного заголовкаN, то показываются текстN и меткаN. {| |- |<pre><nowiki> |заголовок1 = {{{заголовок1|}}} |метка1 = {{{метка1|}}} |текст1 = {{{текст1|}}} </nowiki></pre> |} {| |- |<pre><nowiki> |заголовок1 = заголовок_текст |метка1 = метка_текст |текст1 = текст_текст </nowiki></pre> | {| class="wikitable" |- ! заголовок_текст |} |<pre><nowiki> |заголовок1 = |метка1 = метка_текст |текст1 = текст_текст </nowiki></pre> | {| class="wikitable" |- | метка_текст|| текст_текст |} |} === Оформление параметров === Для оформления параметра можно использовать [[w:ru:Википедия:Функции парсера##if|функцию парсера «#if»]]. Например, следующие строки добавят к параметру <code>текст6</code> подпись кг, если этот параметр определён: <pre><nowiki> |метка6 = Масса |текст6 = {{#if:{{{масса|}}} |{{{масса}}} кг}} </nowiki></pre> А расстановку ссылок на страницы можно организовать с помощью [[w:ru:Википедия:Функции парсера##switch:|«#switch»]], например: <pre><nowiki> |метка6 = Раса |текст6 = {{#switch:{{{раса|}}} |Европеоиды = [[Европеоидная раса|Европеоиды]] |Негроиды = [[Негроидная раса|Негроиды]] |Монголоиды = [[Монголоидная раса|Монголоиды]] |{{{раса|}}} }} </nowiki></pre> == Пустой шаблон == <pre> {{Карточка |имя = {{subst:PAGENAME}} |автозаголовки = да |стиль_вверху = |стиль_заголовков = |стиль_внизу = |вверху = |вверху2 = |изображение = |заголовок1 = |метка2 = |текст2 = |метка3 = |текст3 = |метка4 = |текст4 = |метка5 = |текст5 = |метка6 = |текст6 = |метка7 = |текст7 = |метка8 = |текст8 = |метка9 = |текст9 = |метка10 = |текст10 = ... |меткаN = |текстN = |внизу = }}<noinclude> {{doc}} </noinclude></pre> {{скрытый|Заголовок=11-20|Содержание=<pre> |метка11 = |текст11 = |метка12 = |текст12 = |метка13 = |текст13 = |метка14 = |текст14 = |метка15 = |текст15 = |метка16 = |текст16 = |метка17 = |текст17 = |метка18 = |текст18 = |метка19 = |текст19 = |метка20 = |текст20 = </pre>}} {{скрытый||Заголовок=21-30|Содержание=<pre> |метка21 = |текст21 = |метка22 = |текст22 = |метка23 = |текст23 = |метка24 = |текст24 = |метка25 = |текст25 = |метка26 = |текст26 = |метка27 = |текст27 = |метка28 = |текст28 = |метка29 = |текст29 = |метка30 = |текст30 = </pre>}} {{скрытый||Заголовок=31-40|Содержание=<pre> |метка31 = |текст31 = |метка32 = |текст32 = |метка33 = |текст33 = |метка34 = |текст34 = |метка35 = |текст35 = |метка36 = |текст36 = |метка37 = |текст37 = |метка38 = |текст38 = |метка39 = |текст39 = |метка40 = |текст40 = </pre>}} {{скрытый||Заголовок=41-50|Содержание=<pre> |метка41 = |текст41 = |метка42 = |текст42 = |метка43 = |текст43 = |метка44 = |текст44 = |метка45 = |текст45 = |метка46 = |текст46 = |метка47 = |текст47 = |метка48 = |текст48 = |метка49 = |текст49 = |метка50 = |текст50 = </pre>}} {{скрытый||Заголовок=51-60|Содержание=<pre> |метка51 = |текст51 = |метка52 = |текст52 = |метка53 = |текст53 = |метка54 = |текст54 = |метка55 = |текст55 = |метка56 = |текст56 = |метка57 = |текст57 = |метка58 = |текст58 = |метка59 = |текст59 = |метка60 = |текст60 = </pre>}} == Примерный шаблон для карточки персоны == <pre>{{Карточка |имя = {{subst:PAGENAME}} |автозаголовки = да |стиль_вверху = |стиль_заголовков = |стиль_внизу = |вверху = {{карточка/имя|{{{имя|}}}}} |вверху2 = {{карточка/оригинал имени|{{{оригинал имени|}}}}} |изображение = {{Карточка/изображение|{{{фото|}}}|caption={{{описание изображения|}}}|size={{{ширина|}}}}} |метка1 = Имя при рождении |текст1 = {{{имя при рождении|}}} |метка2 = Дата рождения |текст2 = {{{дата рождения|}}} |метка3 = Место рождения |текст3 = {{{место рождения|}}} |метка4 = Дата смерти |текст4 = {{{дата смерти|}}} |метка5 = Место смерти |текст5 = {{{место смерти|}}} |метка6 = Гражданство |текст6 = {{{гражданство|}}} |метка7 = Сценические имена / Прозвище |текст7 = {{{прозвище|}}} |заголовок8 = {{{сайт|}}} }}</pre> == См. также == * [[вп:Википедия:Шаблоны-карточки|Википедия:Шаблоны-карточки]] * {{t|Универсальная карточка}} * {{t|Навигационная таблица}} — для создания горизонтальных навигационных таблиц (предпочтительный вертикальных, иногда делаемых на карточке) * {{t|Карточка/блок}} — для создания кусков, вставляемых в разные карточки * [[:Категория:Шаблоны:Подстраницы шаблона Карточка|Подстраницы шаблона Карточка]] * [[w:ru:Участник:Jack who built the house/alignTemplateParameters.js|Участник:Jack who built the house/alignTemplateParameters.js]] <includeonly> [[Категория:Шаблоны-карточки|*]] [[Категория:Шаблоны:Мета-шаблоны]] </includeonly> ae10a532e2d2584c783d40f5a375419a0946b865 Шаблон:Ifsubst 10 238 577 2021-08-30T19:34:36Z ruwiki>WerySkok 0 1 версия импортирована: Шаблон:Шаблоны для документирования wikitext text/x-wiki {{ {{{|safesubst:}}}#ifeq:{{ {{{|safesubst:}}}NAMESPACE}}|{{NAMESPACE}} |{{{no|{{{2|}}}}}} |{{{yes|{{{1|}}}}}} }}<noinclude> {{Documentation}} </noinclude> 4f51452ff12b7e72ad15c39cba7e3cc7a76b39d4 Шаблон:Optp 10 239 579 2021-08-30T19:34:41Z ruwiki>WerySkok 0 1 версия импортирована: Шаблон:Шаблоны для документирования wikitext text/x-wiki {{{{{|safesubst:}}}#invoke: Template call code | onlyParams }}<noinclude>{{doc}}</noinclude> 3e116ca0e893f9ea7b938dae72067678b03bc173 Шаблон:Optp/color 10 240 581 2021-08-30T19:34:42Z ruwiki>WerySkok 0 1 версия импортирована: Шаблон:Шаблоны для документирования wikitext text/x-wiki {{{{{|safesubst:}}}ifsubst|1=<!-- --><code style="color: {{optp/color}};">{{{1}}}</code>|2=<!-- --><nowiki>#</nowiki>888888<!-- -->}}<noinclude> [[Категория:Шаблоны:Подстраницы шаблонов]] [[Категория:Шаблоны:Цвет]] [[Категория:Шаблоны:Используемые с подстановкой]] </noinclude> 571a67174168634a24211fe1d5fcaa4727e150f1 Шаблон:Пример 10 241 583 2021-08-30T19:35:05Z ruwiki>WerySkok 0 1 версия импортирована: Шаблон:Шаблоны для документирования wikitext text/x-wiki <includeonly>{{#invoke:Example|main}}</includeonly><noinclude>{{doc}}</noinclude> 6c4efd62aa820f26f326813cddd4cfd909b9bd7a Модуль:Example 828 242 585 2021-08-30T19:35:08Z ruwiki>WerySkok 0 1 версия импортирована: Шаблон:Шаблоны для документирования Scribunto text/plain local p = {} -- используется для того, чтобы можно было удалять элементы из таблицы local function copy(other) local res = {} for k,v in pairs(other) do res[k] = v end return res end -- вызов шаблона, при ошибке возвращает пустую строку local function expand(frame, tname, targs) local success, result = pcall( frame.expandTemplate, frame, {title = tname, args = targs} ) if success then return result else return '' end --return frame:expandTemplate({title = tname, args = args}) end --предотвращает обработку вики-текста в отображении образца local function nowiki(str) local res = str str = mw.text.unstripNoWiki(str) str = string.gsub(str, '%[', '&#91;') str = string.gsub(str, '%]', '&#93;') str = string.gsub(str, '<', '&lt;') str = string.gsub(str, '>', '&gt;') str = string.gsub(str, '{', '&#123;') str = string.gsub(str, '|', '&#124;') str = string.gsub(str, '}', '&#125;') str = string.gsub(str, '\'', '&#39;') str = string.gsub(str, '"', '&quot;') str = string.gsub(str, '(://)', '<span>%1</span>') return str end --удаляет из параметров вписанные через HTML-сущности "<nowiki>" и заменяет "{{=}}" на "=" для вызова шаблона local function process_nowiki_equals(str) str = str:gsub('&lt;nowiki>', ''):gsub('&lt;/nowiki>', '') :gsub('&lt;nowiki&gt;', ''):gsub('&lt;/nowiki&gt;', '') :gsub('&#123;&#123;&#61;&#125;&#125;', '=') :gsub('&#123;{&#61;}&#125;', '=') :gsub('{&#123;&#61;&#125;}', '=') :gsub('{{=}}', '=') :gsub('&amp;', '&') return str end function p.main(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end local yesno = require('Module:Yesno') local args = copy(getArgs(frame, {trim = false, removeBlanks = false})) --copy(frame.args) local tag = args._tag local container = args._container or nil local ucFirst = yesno(args._u, false) local link = yesno(args._link, false) local sep = args._sep and args._sep .. ' ' local endl = args._endl or '' local prefix = args._prefix or args['_pre-text'] or '' local postfix = args._postfix or args['_post-text'] or '' local nobr = yesno(args._nobr, false) local spaced = yesno(args._spaced, false) local nocat = yesno(args._nocat, false) local style = args._style if style == '' then style = nil end -- передаётся шаблоном {{стопка примеров}}, один разделитель на все примеры local comment_sep = args._comment_sep -- полезно в шаблоне {{стопка примеров}} (это просто текст в конце) local after = args._after or args._comment -- полезно в шаблоне {{стопка примеров}} (это просто текст в начале) local before = args._before and args._before .. ' ' or '' if style == 'pre' then if not (tag or container) then container = 'pre' end sep = sep or '\n' elseif style == '*pre' then if not (tag or container) then container = '*pre' end sep = sep or '\n' elseif style == 'pre↓' then if not (tag or container) then container = 'pre' end -- содержимое шаблона {{sp↓|50%||-0.5em}} sep = sep or '<div style="margin:-0.5em 50% 0.7em;"><span style="font-size:150%;">↓</span></div>\n' elseif style == '*pre↓' then if not (tag or container) then container = '*pre' end -- содержимое шаблона {{sp↓|50%||-0.5em}} sep = sep or '<div style="margin:-0.5em 50% 0.7em;"><span style="font-size:150%;">↓</span></div>\n' elseif style == 'wikitable' then if not (tag or container) then tag = 'kbd' end sep = sep or '\n| ' comment_sep = '\n| ' end if not (tag or container) then tag = 'code' end if not sep then sep = '→ ' end if not comment_sep then comment_sep = ' &nbsp;' end if (after) then if not style then after = '<small>' .. after .. '</small>' end after = comment_sep .. after end if not after then after = '' end local nwt if tag then nwt = mw.html.create(tag):tag(tag) -- "no-wiki tag", внутри него шаблон не вызывается if nobr then nwt:css('white-space', 'nowrap') end end local content = nowiki(prefix) .. '{{' -- для накопления содержимого тэга local tname = args._template or args[1] if tname == nil then -- если имя шаблона содержит знак "=" (работает, только если нет неименованных параметров) local nextfunc, static, cur = pairs(args) local k, v = nextfunc(static, cur) if k ~= nil and type(k) ~= 'number' and not k:find('^_') then -- именованные параметры, исключая модификаторы внешнего вида tname = k .. "=" .. v args[k] = nil --больше этот параметр нам не пригодится end end if tname == '' or tname == nil then -- при опущенном первом параметре берём имя шаблона из названия страницы local ru = mw.language.new('ru') local currentTitle = mw.title.getCurrentTitle().rootText if not ucFirst and ((ru:uc(currentTitle) ~= currentTitle and -- названия со всеми заглавными буквами not mw.ustring.match(currentTitle, '^[А-Яа-яA-Za-z]+:?[А-ЯA-Z]') -- Книга:Литературное наследство, TranslateDate ) or #currentTitle == 1 ) then tname = ru:lcfirst(currentTitle) else tname = currentTitle end end -- Имя вызываемого шаблона в неименованном первом параметре (или же взято из названия страницы или -- из именованного параметра в отсутствие неименованных — в следующей строчке вреда нет в любом случае), -- больше его обрабатывать не надо if args._template == nil then table.remove(args,1) end if link then content = content .. '[[Шаблон:' .. tname .. '|' .. tname .. ']]' else content = content .. tname end content = content .. endl local targs, equals_pos, param, value, left_shift = {}, 0, '', '', 0 for k, v in pairs(args) do if type(k) == 'number' then -- неименованные параметры equals_pos = v:find('=') if equals_pos and v:find('{{=}}') == equals_pos-2 then equals_pos = nil end if equals_pos then -- содержащие "=" преобразуем в именованные param = v:sub(1, equals_pos-1) value = v:sub(equals_pos+1) targs[param] = process_nowiki_equals(value) content = content .. (spaced and ' ' or '') .. '&#124;' .. nowiki(param) .. '=' .. nowiki(value) .. endl left_shift = left_shift + 1 -- переменная нужна, чтобы квазинумерованные параметры, переданные через "{{=}}", -- не сбивали порядок else -- истинно неименованные targs[k - left_shift] = process_nowiki_equals(v) content = content .. (spaced and ' ' or '') .. '&#124;' .. nowiki(v) .. endl end elseif not k:find('^_') then -- именованные параметры, исключая модификаторы внешнего вида targs[k] = process_nowiki_equals(v) content = content .. (spaced and ' ' or '') .. '&#124;' .. nowiki(k) .. '=' .. nowiki(v) .. endl end end if spaced then content = content .. ' ' end content = content .. '}}' .. nowiki(postfix) if container then local container_args = {} container_args[1] = content nwt = expand(frame, container, container_args) else nwt:wikitext(content):done() end if nocat then targs['nocat'] = 1 end expand_result = tostring(expand(frame, tname, targs)) if expand_result:sub(1, 2) == '{|' then sep = sep .. '\n' end return before .. tostring(nwt) .. ' ' .. sep .. prefix .. expand_result .. postfix .. after end return p bbcc2db5eb699c86d081437122681304ac0c12b8 Шаблон:Namespace detect 10 233 533 2021-08-30T19:43:11Z ruwiki>WerySkok 0 wikitext text/x-wiki {{#switch: {{lc: <!--Lower case the result--> <!--If no or empty "demospace" parameter then detect namespace--> {{#if:{{{demospace|}}} | {{{demospace}}} | {{#ifeq:{{NAMESPACE}}|{{ns:0}} | main | {{#ifeq:{{NAMESPACE}}|{{TALKSPACE}} | {{#if:{{{talk|}}} | talk | {{#if:{{{andtalk|}}}|{{SUBJECTSPACE}}|talk}} }} | {{NAMESPACE}} }} }} }} }} <!-- Only one of the lines below will be executed --> <!-- Respecting empty parameters on purpose --> | main = {{{main| {{{other|}}} }}} | talk | обсуждение = {{{talk| {{{other|}}} }}} | user | участник = {{{user| {{{other|}}} }}} | wikipedia | википедия = {{{wikipedia| {{{other|}}} }}} | file | image | файл = {{{file| {{{image| {{{other|}}} }}} }}} | mediawiki | медиавики = {{{mediawiki| {{{other|}}} }}} | template | шаблон = {{{template| {{{other|}}} }}} | help | справка = {{{help| {{{other|}}} }}} | category | категория = {{{category| {{{other|}}} }}} | portal | портал = {{{portal| {{{other|}}} }}} | other | #default = {{{other|}}} <!--"demospace=other" or a new namespace--> }}<!--End switch--><noinclude> {{documentation}}{{Указание авторства русскоязычной Википедии}} </noinclude> 058c2deda5bf3cd3190672c4b14ab9f0c072ce03 Шаблон:= 10 243 589 2021-08-30T20:10:13Z ruwiki>WerySkok 0 1 версия импортирована wikitext text/x-wiki =<noinclude>{{doc}}{{Указание авторства русскоязычной Википедии}}</noinclude> 014d0de3d5673019255be0e21b88cdb2037871db Шаблон:Docpage 10 178 529 2021-08-30T20:10:36Z ruwiki>WerySkok 0 1 версия импортирована wikitext text/x-wiki <includeonly>{{#ifeq: {{SUBPAGENAME}} | doc | {{fmbox | class = hlist nowraplinks | style = margin-bottom:1em; background:#eaf3ff; border:1px solid #a3caff; | image = [[Файл:OOjs UI icon info.svg|24px|link=|alt=]] | text = <div> * [[:{{#titleparts: {{SUBJECTPAGENAME}} | -1 }}]] * [[:{{SUBJECTPAGENAME}}|Документация]] * [[{{#titleparts: {{TALKPAGENAME}} | -1 }}|Обсуждение]] * [[Служебная:Whatlinkshere/{{#titleparts: {{SUBJECTPAGENAME}} | -1 }}|Где используется]] <!-- {{#ifeq: {{NAMESPACE}} | {{ns:Template}} | ** {{Параметры шаблона|{{#titleparts: {{PAGENAME}} | -1 }}}} }} --></div><!-- -->{{#if: {{{nocat|}}} || {{#ifexist: {{NAMESPACE}}:{{BASEPAGENAME}} || [[Категория:Шаблоны:Документация несуществующих шаблонов]] }} }} }}{{#if: {{{nocat|}}} || {{#ifeq: {{NAMESPACE}} | Модуль | [[Категория:Модули:Документация]] | [[Категория:Шаблоны:Документация]] }} }} }}</includeonly><noinclude>{{doc}}</noinclude> 7f27a8c87a1da2f25ea94fb8ad4600fc9bd009a5 Шаблон:Tc 10 244 591 2021-08-30T20:10:52Z ruwiki>WerySkok 0 1 версия импортирована wikitext text/x-wiki {{{{{|safesubst:}}}#invoke: Template call code | withParams | _tag = {{{_tag|code}}} }}<noinclude>{{doc}}</noinclude> db6f042f5bfd10e28e4554066fa696babcc884b2 Шаблон:Карточка 10 129 639 2021-08-30T20:11:34Z ruwiki>WerySkok 0 1 версия импортирована wikitext text/x-wiki <table class="infobox {{{класс_тела|}}}" style="{{{стиль_тела|}}}" {{#if:{{{имя|}}}|{{#ifeq:{{{имя|}}}|-||data-name="{{{имя}}}"}}}}><!-- Вверху0 -->{{#if:{{{вверху0|}}}|<tr><td colspan="2" class="{{{класс_вверху0|}}}" style="text-align:center; {{{стиль_вверху0|}}}">{{{вверху0}}}</td></tr>}}<!-- Вверху -->{{#if:{{{вверху|}}}|<tr><th colspan="2" class="infobox-above {{{класс_вверху|}}}" style="{{{стиль_вверху|}}}">{{{вверху}}}</th></tr>}}<!-- Вверху2 -->{{#if:{{{вверху2|}}}|<tr><td colspan="2" class="{{{класс_вверху2|}}}" style="text-align:center; {{{стиль_вверху2|}}}">{{{вверху2}}}</td></tr>}}<!-- Вверху3 -->{{#if:{{{вверху3|}}}|<tr><td colspan="2" class="{{{класс_вверху3|}}}" style="text-align:center; {{{стиль_вверху3|}}}">{{{вверху3}}}</td></tr>}}<!-- Изображение -->{{#if:{{{изображение|}}}|<tr><td colspan="2" class="infobox-image {{{класс_изображения|}}}" style="{{{стиль_изображения|}}}"> {{{изображение}}} {{#if:{{{подпись|}}}| <div class="media-caption" style="{{{стиль_подписи|}}}">{{{подпись}}}</div>}}</td></tr>}}<!-- Изображение2 -->{{#if:{{{изображение2|}}}|<tr><td colspan="2" class="infobox-image {{{класс_изображения2|}}}" style="{{{стиль_изображения2|}}}"> {{{изображение2}}} {{#if:{{{подпись2|}}}| <div class="media-caption" style="{{{стиль_подписи2|}}}">{{{подпись2}}}</div>}}</td></tr>}}<!-- Изображение3 -->{{#if:{{{изображение3|}}}|<tr><td colspan="2" class="infobox-image {{{класс_изображения3|}}}" style="{{{стиль_изображения3|}}}"> {{{изображение3}}} {{#if:{{{подпись3|}}}| <div class="media-caption" style="{{{стиль_подписи3|}}}">{{{подпись3}}}</div>}}</td></tr>}}<!-- Строки -->{{#invoke:Infobox|renderLines}}<!-- Внизу -->{{Карточка/внизу| стиль_внизу_общий={{{стиль_внизу|}}}| класс_внизу={{{класс_внизу|}}}| внизу={{{внизу|}}}}}<!-- Внизу N -->{{#invoke:Transclude|npc|Карточка/внизу| стиль_внизу_общий={{{стиль_внизу|}}}| стиль_внизу=| класс_внизу=| внизу=}} </table><includeonly><!-- статьи -->{{#if:{{NAMESPACE}}||<!-- -->{{#if:{{{имя|}}}||[[Категория:Статьи с шаблонами-карточками без имени]]}}<!-- -->{{#ifeq:{{{имя|}}}|{{subst:PAGENAME}}|[[Категория:Статьи с шаблонами-карточками без имени]]}}<!-- -->}}<!-- шаблоны -->{{#ifeq:{{NAMESPACENUMBER}}|10|<!-- -->{{#if:{{{имя|}}}||[[Категория:Шаблоны-карточки без имени]]}}<!-- -->{{#ifeq:{{{имя|}}}|{{subst:PAGENAME}}|[[Категория:Шаблоны-карточки без имени]]}}<!-- -->{{#if:{{{название|}}}{{{стиль_названия|}}}|[[Категория:Шаблоны с использованием параметра «название» в шаблоне «Карточка»]]}}<!-- -->{{#if:{{{подпись|}}}{{{стиль_подписи|}}}{{{подпись2|}}}{{{стиль_подписи2|}}}{{{подпись3|}}}{{{стиль_подписи3|}}}|[[Категория:Шаблоны с использованием параметра «подпись» в шаблоне «Карточка»]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_тела|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_названия|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_вверху|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_вверху2|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_вверху3|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_подписи|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_подписи2|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_подписи3|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_заголовков|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_меток|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_текста|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_внизу|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifeq:{{{имя|}}}|{{PAGENAME}}| [[Категория:Шаблоны-карточки по алфавиту|{{ucfirst:{{без начала|{{PAGENAME}}|Карточка }}}}]]}}<!-- -->}}<!-- любое пространство имён -->{{#if:{{{название|}}}{{{стиль_названия|}}}|[[Категория:Страницы с использованием параметра «название» в шаблоне «Карточка»]]}}<!-- -->{{#if:{{{подпись|}}}{{{стиль_подписи|}}}{{{подпись2|}}}{{{стиль_подписи2|}}}{{{подпись3|}}}{{{стиль_подписи3|}}}|[[Категория:Страницы с использованием параметра «подпись» в шаблоне «Карточка»]]}}</includeonly><noinclude>{{doc}}{{Указание авторства русскоязычной Википедии}}</noinclude> 8b14ccc682362e6ed5a194621133805aea17ab0d Шаблон:Optp/comment 10 245 593 2021-08-30T20:28:35Z ruwiki>WerySkok 0 1 версия импортирована wikitext text/x-wiki <p style="font-size:85%;">Серым {{#ifeq: {{{1|}}} | 1 | показан необязательный параметр | показаны необязательные параметры }}.</p><noinclude> {{doc-inline}} * {{пример|optp/comment}} * {{пример|optp/comment|1}} {{doc-end}} [[Категория:Шаблоны:Подстраницы шаблонов]] </noinclude> 57a6d9eaf58c69ac5e07d5a55c4de17d34d427bf Шаблон:^ 10 246 595 2021-08-30T20:28:46Z ruwiki>WerySkok 0 1 версия импортирована wikitext text/x-wiki <div style=margin-top:{{#if:{{{1|}}}|{{{1}}}|2em}}></div><noinclude>{{doc}}<!-- Пожалуйста, добавляйте категории и интервики на страницу документации! --></noinclude> 8a2941bfb74cc487b19b1ce656a0d7b49cfb9a8e Шаблон:Sp↓ 10 249 601 2021-08-30T20:29:10Z ruwiki>WerySkok 0 1 версия импортирована wikitext text/x-wiki <div style="margin-left:{{#if: {{{1|}}} | {{{1}}} | 1.3em }}; {{#if: {{{2|}}} | margin-top:{{{2}}}; }} margin-bottom:{{#if: {{{3|}}} | {{{3}}} | 0.7em }};"><span style="font-size:{{#if: {{{size|}}} | {{{size}}} | {{#ifeq: {{str find|{{{1|}}}|%}} | -1 | 120% | 150% }} }};">↓</span></div><noinclude>{{doc}}</noinclude> e0d0479cdd64d3e90be2c1c2d1b3c3502312f926 Шаблон:Днш 10 250 603 2021-08-30T20:29:11Z ruwiki>WerySkok 0 1 версия импортирована wikitext text/x-wiki #REDIRECT [[Шаблон:Другие названия шаблона]] 310154c4badc00ae3faf727456b5aba85e337ba6 Шаблон:Abbr 10 232 517 2021-08-31T11:40:52Z ruwiki>WerySkok 0 wikitext text/x-wiki <includeonly>{{#switch: {{{3|1}}} | 0 = <abbr title="{{#tag:nowiki|{{replace|{{{2}}}|"|&quot;}}}}">{{{1}}}</abbr> | 1 = [[{{{1}}}|<abbr title="{{#tag:nowiki|{{replace|{{{2}}}|"|&quot;}}}}">{{{1}}}</abbr>]] | 2 = [[{{{2}}}|<abbr title="{{#tag:nowiki|{{replace|{{{2}}}|"|&quot;}}}}">{{{1}}}</abbr>]] | #default = [[{{{3}}}|<abbr title="{{#tag:nowiki|{{replace|{{{2}}}|"|&quot;}}}}">{{{1}}}</abbr>]] }}</includeonly><noinclude>{{doc}}{{Указание авторства русскоязычной Википедии}}</noinclude> adac845cdff938e70ffb8d2c92101be40d204e3b Шаблон:Abbr/doc 10 248 599 2021-08-31T11:48:42Z ruwiki>WerySkok 0 wikitext text/x-wiki {{docpage}} Этот шаблон выделяет [[w:ru:Аббревиатура|аббревиатуру]] подчёркиванием и добавляет к ней всплывающую подсказку с расшифровкой. Он во многом похож на шаблон {{tl|comment}}. Шаблон может установить ссылку на статью, имя которой — значение 1-го, 2-го или 3-го параметра, например: {{abbr|РФ|Российская Федерация|w:ru:Россия}}. {{днш|аббревиатура|аббр}} == Использование == {{tc||''аббревиатура''|''расшифровка''{{optp|''№ параметра для ссылки или 0, чтобы подавить ссылку''}}}} {{optp/comment}}{{^|1em}} Необязательный третий параметр указывает, какой из параметров использовать для ссылки в качестве названия статьи. * <code>0</code> — подавить ссылку * <code>1</code> (по умолчанию) — использовать 1-й параметр (<code>''аббревиатура''</code>) * <code>2</code> — использовать 2-й параметр (<code>''расшифровка''</code>) * другое — использовать 3-й (этот же) параметр == Примеры == * Ссылка подавлена: : {{пример||ПТЗ|Павлодарский тракторный завод|0}} * Ссылка по умолчанию или явно использует содержимое 1-го параметра: : {{tc||w:ru:АН СССР|Академия наук СССР}}<br><span style="margin-left: 6px;">или</span><br>{{пример||w:ru:АН СССР|Академия наук СССР|1|_sep={{sp↓|||0}}}} <!-- интервики на википедию чтоб не требовало страниц --> * Ссылка использует содержимое 2-го параметра: : {{пример||ПАВ|w:ru:поверхностно-активные вещества|2}} * Ссылка на произвольную страницу в 3-м параметре: : {{пример||ПАВ|поверхностно-активные вещества|w:ru:Психоактивные вещества}} : В данном случае ПАВ расшифровано как «поверхностно-активные вещества», ссылка указывает на статью «[[w:ru:Психоактивные вещества|Психоактивные вещества]]». == Технические ограничения == Технические ограничения те же, что и в шаблоне {{tl|comment}}. * Если в параметрах шаблона есть знак <code>=</code>, то, как и в любом другом шаблоне, приходится использовать явные номера параметров: {{tc|comment|1{{=}}текст|2{{=}}подсказка}}. * В некоторых браузерах длина всплывающей подсказки ограничена. Например, в браузере Mozilla Firefox до третьей версии подсказки были однострочными. * Пользователи [[w:ru:смартфон|смартфонов]] и [[w:ru:Планшетный компьютер|планшетных компьютеров]], как правило, не имеют возможности увидеть всплывающую подсказку, поэтому используйте данный шаблон только там, где это действительно необходимо. <includeonly> [[Категория:Шаблоны:Форматирование]] [[Категория:Шаблоны:Внутренние ссылки]] </includeonly> 060aec5d84b5320d02f9c95e1cd0427e110f1315 Шаблон:Другие названия шаблона 10 247 597 2021-08-31T11:50:38Z ruwiki>WerySkok 0 wikitext text/x-wiki <includeonly>[[w:ru:ВП:Перенаправления|{{#if:{{{2|}}}|Другие названия|Другое название}}]] этого шаблона{{#if:{{{2|}}}|&#58;|&nbsp;—}} <!-- -->{{#if:{{{1|}}}|{{t|{{{1}}}|noredir}} |<strong class=error>Не указано ни одного альтернативного названия!</strong>}}<!-- -->{{#if:{{{2|}}}|, {{t|{{{2}}}|noredir}} }}<!-- -->{{#if:{{{3|}}}|, {{t|{{{3}}}|noredir}} }}<!-- -->{{#if:{{{4|}}}|, {{t|{{{4}}}|noredir}} }}<!-- -->{{#if:{{{5|}}}|, {{t|{{{5}}}|noredir}} }}<!-- -->{{#if:{{{6|}}}|, {{t|{{{6}}}|noredir}} }}<!-- -->{{#if:{{{7|}}}|, {{t|{{{7}}}|noredir}} }}<!-- -->{{#if:{{{8|}}}|, {{t|{{{8}}}|noredir}} }}<!-- -->{{#if:{{{9|}}}|&#32;[{{fullurl:Служебная:Ссылки сюда/{{FULLPAGENAMEE}}|hidelinks=1&hidetrans=1}} и др.]|{{#if:{{{comment|}}}|&nbsp;({{{comment}}})}}}}.</includeonly><noinclude>{{doc}}{{Указание авторства русскоязычной Википедии}}</noinclude> 7b543dddf959926ff3a8b3d1ae7894515a88b0a0 Шаблон:Big 10 73 631 118 2021-08-31T11:51:12Z ruwiki>WerySkok 0 wikitext text/x-wiki <span style="font-size:120%;">{{{1}}}</span><noinclude> {{documentation}}{{Указание авторства русскоязычной Википедии}} <!-- PLEASE ADD CATEGORIES TO THE /doc SUBPAGE, THANKS --> </noinclude> c98715ace316ced3e534c85a0061a40c996f9cec Шаблон:Clear 10 188 519 420 2021-08-31T11:51:48Z ruwiki>WerySkok 0 wikitext text/x-wiki <div style="clear:{{{1|both}}};"></div><noinclude>{{doc}}{{Указание авторства русскоязычной Википедии}}</noinclude> 658ab2d07ec1af4be2ebb95507ab98803c483513 Шаблон:Doc 10 171 521 2021-08-31T11:52:10Z ruwiki>WerySkok 0 wikitext text/x-wiki <includeonly>{{doc/begin|{{SUBJECTSPACE}}:{{PAGENAME:{{{1|{{SUBJECTPAGENAME}}/doc}}}}}|editsection={{{editsection|}}}}} {{#if:{{{1|}}}|{{#ifexist:{{{1}}}|{{{{{1}}}|{{{2|}}}|{{{3|}}}|{{{4|}}}|{{{5|}}}}}|{{#ifexist:{{SUBJECTSPACE}}:{{{1}}}|{{{{{1}}}|{{{2|}}}|{{{3|}}}|{{{4|}}}|{{{5|}}}}}|{{Документировать|{{{1}}}}}}}}}|{{#ifexist:{{SUBJECTPAGENAME}}/doc|{{{{SUBJECTPAGENAME}}/doc}}|{{Документировать|{{SUBJECTPAGENAME}}/doc}}}}}} {{doc/end}}</includeonly><noinclude> {{doc}}{{Указание авторства русскоязычной Википедии}} <!-- [Rus]: Добавляйте категории и интервики на подстраницу /doc, не сюда! [Eng]: Please add categories and interwiki links to the /doc subpage, not here! --> </noinclude> b75033813bba7eb90a8976d597febd1d93bcecab Шаблон:Doc/begin 10 172 523 2021-08-31T11:52:31Z ruwiki>WerySkok 0 wikitext text/x-wiki <includeonly><templatestyles src="Шаблон:Doc/styles.css" />{{clear}}<div>{{якорь|Документация|doc}}</div> <div class="ts-doc-doc"> <div class="ts-doc-header"> <div class="ts-doc-heading">Документация</div> {{#if: {{{inline|}}} || {{tlinks|lc={{{1}}}|nowatch=yes}} }} </div> <div class="ts-doc-content"></includeonly><noinclude>{{doc}}{{Указание авторства русскоязычной Википедии}}</noinclude> aafe3c200059d98000a15745eb3a16b332048322 Шаблон:Doc/styles.css 10 173 527 2021-08-31T11:54:21Z ruwiki>WerySkok 0 sanitized-css text/css .ts-doc-doc { background-color: #eaf3ff; border: 1px solid #a3caff; margin-top: 1em; } .ts-doc-header { background-color: #c2dcff; padding: .642857em 1em .5em; overflow: hidden; } .ts-doc-header .ts-tlinks-tlinks { line-height: 24px; } .ts-doc-header .ts-tlinks-tlinks a.external { color: #0645ad; } .ts-doc-header .ts-tlinks-tlinks a.external:visited { color: #0b0080; } .ts-doc-header .ts-tlinks-tlinks a.external:active { color: #faa700; } .ts-doc-content { padding: .214286em 1em; } .ts-doc-content:after { content: ''; clear: both; display: block; } .ts-doc-heading { display: inline-block; padding-left: 30px; background: url(//upload.wikimedia.org/wikipedia/commons/c/ca/OOjs_UI_icon_info.svg) center left/24px 24px no-repeat; height: 24px; line-height: 24px; font-size: 13px; font-weight: 600; letter-spacing: 1px; text-transform: uppercase; } .ts-doc-content > *:first-child, .ts-doc-footer > *:first-child { margin-top: .5em; } .ts-doc-content > *:last-child, .ts-doc-footer > *:last-child { margin-bottom: .5em; } .ts-doc-footer { background-color: #eaf3ff; border: 1px solid #a3caff; padding: .214286em 1em; margin-top: .214286em; margin-bottom: .214286em; font-style: italic; } @media (max-width: 719px) { .ts-doc-header .ts-tlinks-tlinks { float: none; } } /* Данный шаблон использует материал из страницы [[w:ru:Шаблон:Doc/styles.css]] с русскоязычной Википедии, который выпущен под лицензией Creative Commons Attribution-ShareAlike 3.0 Unported. [[Категория:Шаблоны:Подстраницы CSS]] */ 569be9051ed08a2fc9715c629fb275f499513915 Шаблон:Join 10 150 531 342 2021-08-31T11:54:56Z ruwiki>WerySkok 0 wikitext text/x-wiki {{<includeonly>safesubst:</includeonly>#invoke:Separated entries|main|separator={{{separator|}}}}}<noinclude> {{doc}}{{Указание авторства русскоязычной Википедии}} <!-- Категории — на подстраницу /doc, интервики — в Викиданные. --> </noinclude> af3b635654ed05178cb618c5ae74d630f683b14b Шаблон:Ombox 10 20 609 2021-08-31T11:55:31Z ruwiki>WerySkok 0 wikitext text/x-wiki {{#invoke:Message box|ombox}}<noinclude> {{doc}}{{Указание авторства русскоязычной Википедии}}<!-- Add categories and interwikis to the /doc subpage, not here! --></noinclude> d6812e2b9ef235ed760e3d51553c6a00fbddec09 Шаблон:Replace 10 145 535 2021-08-31T11:55:45Z ruwiki>WerySkok 0 wikitext text/x-wiki {{{{{|safesubst:}}}#invoke:String|replace|source={{{1}}}|{{{2}}}|{{{3}}}|count={{{count|}}}}}<noinclude>{{doc}}{{Указание авторства русскоязычной Википедии}}</noinclude> 1e93df448b55000320615b7fb5a0678e470ff5ff Шаблон:Str left 10 146 537 334 2021-08-31T11:55:53Z ruwiki>WerySkok 0 wikitext text/x-wiki {{<includeonly>safesubst:</includeonly>padleft:|{{{2|1}}}|{{{1|}}}}}<noinclude> {{doc}}{{Указание авторства русскоязычной Википедии}} </noinclude> c84e4fa3913bb778eebb4e7967691f2a54ccf7f4 Шаблон:Str len 10 166 539 374 2021-08-31T11:56:07Z ruwiki>WerySkok 0 wikitext text/x-wiki {{{{{|safesubst:}}}#invoke:String|len|s={{{1|}}}}}<noinclude> {{doc}}{{Указание авторства русскоязычной Википедии}} <!-- Add categories and interwikis to the /doc subpage, not here! --> </noinclude> 64072366351eb0f17ebd1d769946190837e1fc9d Шаблон:Str rightc 10 167 541 376 2021-08-31T11:56:22Z ruwiki>WerySkok 0 wikitext text/x-wiki {{<includeonly>safesubst:</includeonly>Str sub|{{{1}}}|{{<includeonly>safesubst:</includeonly>#expr:{{<includeonly>safesubst:</includeonly>Str len|{{{1}}}}}-{{{2}}}}}|{{{2}}}}}<noinclude>{{doc}}{{Указание авторства русскоязычной Википедии}}</noinclude> a3a090a23406df9276554e488f593ed68cfd2e03 Шаблон:Str sub 10 164 543 370 2021-08-31T11:56:34Z ruwiki>WerySkok 0 wikitext text/x-wiki <includeonly>{{{{{|safesubst:}}}#invoke:String|sublength|s={{{1}}}|i={{{2|0}}}|len={{{3|0}}}}}</includeonly><noinclude> {{doc}}{{Указание авторства русскоязычной Википедии}} </noinclude> 23deaf74186354efc10b9054b8b8f2da2dc98a34 Шаблон:Tag 10 72 633 2021-08-31T11:57:02Z ruwiki>WerySkok 0 wikitext text/x-wiki <{{#ifeq: {{{style|}}} | regular | span | code }} class="{{#ifeq: {{{wrap|}}} | yes | wrap | nowrap }}" style="{{#switch: {{{style|}}} | plain = border:none; background:transparent; | regular = | {{{style|}}} }}"><!-- Opening tag -->{{#switch: {{#if: {{{2|}}} | {{{2|}}} | pair }} |c|close = |s|single |o|open |p|pair = {{#ifeq: {{{1|tag}}} | !-- | {{#ifeq: {{{style|}}} | regular | <span class="wp-templatelink">&lt;!--</span> | &lt;!-- }} | {{#ifeq: {{{style|}}} | regular | <span class="wp-templatelink">&lt;</span> | &lt; }}{{{1|tag}}}{{#if: {{{params|{{{p|}}}}}} | &#32;{{{params|{{{p|}}}}}} }} }} }}<!-- Content between tags -->{{#switch: {{#if: {{{2|}}} | {{{2|}}} | pair }} |c|close = {{{content|{{{c|}}}}}} |s|single = &#32;{{#ifeq: {{{style|}}} | regular | <span class="wp-templatelink">/&gt;</span> | /&gt; }} |o|open = {{#ifeq: {{{style|}}} | regular | <span class="wp-templatelink">&gt;</span> | &gt; }}{{{content|{{{c|}}}}}} |p|pair = {{#ifeq: {{{1|tag}}} | !-- || {{#ifeq: {{{style|}}} | regular | <span class="wp-templatelink">&gt;</span> | &gt; }} }}{{{content|{{{c|}}}}}} }}<!-- Closing tag -->{{#switch: {{#if: {{{2|}}} | {{{2|}}} | pair }} |s|single |o|open = |c|close |p|pair = {{#ifeq: {{{1|tag}}} | !-- | {{#ifeq: {{{style|}}} | regular | <span class="wp-templatelink">--&gt;</span> | --&gt; }} | {{#ifeq: {{{style|}}} | regular | <span class="wp-templatelink">&lt;/</span>{{{1|tag}}}<span class="wp-templatelink">&gt;</span> | &lt;/{{{1|tag}}}&gt; }} }} }}<!-- --></{{#ifeq: {{{style|}}} | regular | span | code }}><noinclude>{{doc}}{{Указание авторства русскоязычной Википедии}}</noinclude> 20b34607cde77ca9d1e04d50395bb22f556175d6 Шаблон:Действия для страницы 10 174 555 2021-08-31T11:57:14Z ruwiki>WerySkok 0 wikitext text/x-wiki <templatestyles src="Шаблон:Действия для страницы/styles.css" /><div style="{{#ifeq: {{yesno-yes|{{{right|}}}}} | yes || float:none; }} {{#if: {{{fontsize|}}} | font-size:{{{fontsize|}}}px; }}" class="ts-tlinks-tlinks plainlinks"><span class="mw-editsection-bracket">[</span><!-- -->{{join|separator=<span class="mw-editsection-divider"> &amp;#124; </span> |1={{#ifexist: {{#rel2abs: {{{lc|}}} }} | {{#ifeq: {{{dislooklink|{{{noview|}}}}}} | yes || [[{{{lc}}}|просмотр]] }} }} |2={{#ifexist: {{#rel2abs: {{{lc|}}} }} | [[Special:EditPage/{{#rel2abs: {{{lc}}} }}|править]] }} |3={{#ifexist: {{#rel2abs: {{{lc|}}} }} | {{#ifeq: {{{dishistlink|{{{nohistory|}}}}}} | yes || [[Special:PageHistory/{{#rel2abs: {{{lc}}} }}|история]] }} }} |4={{#ifexist: {{#rel2abs: {{{lc|}}} }} | | [{{fullurl:{{#rel2abs: {{{lc}}} }}|action=edit&redlink=1}} создать] }} |5={{#ifeq: {{{diswatchlink|{{{nowatch|}}}}}} | yes || [{{fullurl:{{#rel2abs: {{{lc}}} }}|action=watch}} следить] }} |6={{#ifeq: {{{disupdlink|{{{noupdate|}}}}}} | yes || <span class="purgelink" data-pagename="{{{lc|{{FULLPAGENAME}}}}}">[[Special:Purge/{{{lc|{{FULLPAGENAME}}}}}|обновить]]</span> }} }}<span class="mw-editsection-bracket">]</span></div><noinclude>{{doc}}{{Указание авторства русскоязычной Википедии}}</noinclude> 8bb7f43b48bc8df9261d9908ae41e529a7ce2b76 Шаблон:Yesno 10 131 551 304 2021-08-31T11:57:38Z ruwiki>WerySkok 0 wikitext text/x-wiki {{<includeonly>safesubst:</includeonly>#switch: {{<includeonly>safesubst:</includeonly>lc: {{{1|¬}}} }} |no |n |нет |false |0 = {{{no|<!-- null -->}}} | = {{{blank|{{{no|<!-- null -->}}}}}} |¬ = {{{¬|}}} |yes |y |да |true |1 = {{{yes|yes}}} |#default = {{{def|{{{yes|yes}}}}}} }}<noinclude> {{Documentation}}{{Указание авторства русскоязычной Википедии}} </noinclude> c4869ee2d8dd9ac37c836c6827b5747ee662c680 Шаблон:Yesno-yes 10 153 553 2021-08-31T11:57:58Z ruwiki>WerySkok 0 wikitext text/x-wiki {{yesno|{{{1}}}|yes={{{yes|yes}}}|no={{{no|no}}}|blank={{{blank|yes}}}|¬={{{¬|yes}}}|def={{{def|yes}}}}}<noinclude>{{doc}}{{Указание авторства русскоязычной Википедии}}</noinclude> 1671b5ddb7308c399e9763990062634cdca2e416 Шаблон:Действия для страницы/styles.css 10 175 557 2021-08-31T11:59:39Z ruwiki>WerySkok 0 sanitized-css text/css .ts-tlinks-tlinks { font-weight: normal; float: right; font-size: 13px; } .ts-tlinks-tlinks .mw-editsection-divider { display: inline; } /* Данный шаблон использует материал из шаблона [[w:ru:Шаблон:Действия для страницы/styles.css]] с русскоязычной Википедии, который выпущен под лицензией Creative Commons Attribution-ShareAlike 3.0 Unported. [[Категория:Шаблоны:Подстраницы CSS]] */ 54f9185e91e3e9570794c39f9c9829c7cab67759 Шаблон:Карточка/внизу 10 137 647 316 2021-09-01T19:26:20Z ruwiki>WerySkok 0 wikitext text/x-wiki <includeonly>{{#if:{{{внизу|}}}|<tr><td colspan="2" class="infobox-below {{{класс_внизу|}}}" style="{{{стиль_внизу_общий|}}};{{{стиль_внизу|}}}">{{{внизу|}}}</td></tr>}}</includeonly><noinclude> {{doc}}{{Указание авторства русскоязычной Википедии}} </noinclude> 716990a6b019cac431163672bf5072536f075925 Шаблон:Якорь 10 236 561 2021-09-01T19:27:56Z ruwiki>WerySkok 0 wikitext text/x-wiki {{#invoke:якорь|main}}<noinclude> {{doc}}{{Указание авторства русскоязычной Википедии}} <!-- Добавляйте категории на страницу документацию, не сюда --> </noinclude> d3f6a8195150483ee5b8b616a2aae7afbd3a3e0b Шаблон:Str find 10 214 587 476 2021-09-01T19:28:50Z ruwiki>WerySkok 0 wikitext text/x-wiki {{ {{{|safesubst:}}}#invoke:String|str_find|source={{{1|}}}|{{{2|}}}}}<noinclude> {{doc}}{{Указание авторства русскоязычной Википедии}} <!-- Add categories and interwikis to the /doc subpage, not here! --> </noinclude> 30ca3557bed0ebaf84cb26b8d708526b29211ed7 Шаблон:Tl 10 162 547 366 2021-09-01T19:29:49Z ruwiki>WerySkok 0 wikitext text/x-wiki {{{{{|safesubst:}}}#invoke: Template call code | withoutParams }}<noinclude>{{doc}}{{Указание авторства русскоязычной Википедии}}</noinclude> c6affa0b33f35b013da6f92eae77096f6a254def Шаблон:OnLua 10 227 641 2021-09-01T19:32:23Z ruwiki>WerySkok 0 wikitext text/x-wiki <includeonly>{{ombox | small = yes | style = width:23em; | image = [[Файл:Lua-logo-nolabel.svg|40px|alt=Лого Lua|link=w:ru:Lua]] | text = {{replace|Этот шаблон {{#if: {{{partly|}}} | частично }} реализован на основе [[w:ru:Lua|Lua]]{{#if:{{{module2|}}}{{{tech2|}}}|&#58;<br><ul><li>}}{{#if:{{{1|}}}{{{tech|}}}|&#32;с использованием {{{tech|{{#if:{{{2|}}}|функции <code>{{#if:{{{line|}}}|[[Module:{{{1}}}#L-{{{line}}}|{{{2}}}()]]|[[{{{funcref|Module:{{{1}}}#{{{2}}}}}}|{{{2}}}()]]}}</code> из&#32;}}{{#if:{{{1|}}}|модуля [[Module:{{{1}}}|{{{1}}}]]}}}}};}}<!-- -->{{#invoke:Transclude|npc|OnLua/Строка| module= |function= |tech= |line= }}.|;.|.}}{{#if:{{{module2|}}}{{{tech2|}}}|</ul>}} {{#if:{{{1|}}}{{{tech|}}}{{{module1|}}}{{{tech1|}}}||<div class="error"><small>'''Не указано название использующегося модуля!'''</small></div>}} }}{{#ifeq:{{SUBPAGENAME}}|{{{doc|doc}}}||{{#if:{{{nocat|}}}||[[Категория:Шаблоны, использующие Scribunto]]{{#if:{{{1|}}}{{{tech|}}}{{{module1|}}}{{{tech1|}}}||[[Категория:Шаблоны, использующие Lua, без указания модуля]]}}}}}}</includeonly><noinclude>{{doc}}{{Указание авторства русскоязычной Википедии}}</noinclude> 18395e40673a4d14410acb745ce1b85e01dce5b7 Шаблон:Doc/end 10 176 525 394 2021-09-01T19:34:08Z ruwiki>WerySkok 0 wikitext text/x-wiki <includeonly></div> </div><templatestyles src="Шаблон:Doc/styles.css" />{{#ifexpr: {{NAMESPACENUMBER}} mod 2 = 1 <!-- Например, [[Обсуждение MediaWiki:Robots.txt]] --> | {{^|1em}} | <div class="ts-doc-footer plainlinks"> {{#ifeq: {{str left|{{PAGENAME}}|9}} | Песочница | | {{#ifeq: {{str rightc|{{PAGENAME}}|10}} | /песочница | | Во избежание поломок страниц, использующих этот {{#ifeq: {{NAMESPACE}} | Модуль | модуль | шаблон }}, экспериментируйте в [[w:ru:Википедия:Правка и тестирование шаблонов в песочнице|песочнице]] <small style="font-style:normal;">({{#ifexist: {{FULLPAGENAME}}/песочница | [{{fullurl:{{FULLPAGENAME}}/песочница|action=edit}} редактировать] {{!}} [{{fullurl:Special:ComparePages|page1={{FULLPAGENAMEE}}&page2={{FULLPAGENAMEE}}/песочница}} разница] {{#ifexist: {{FULLPAGENAME}}/тесты | {{!}} [[{{FULLPAGENAME}}/тесты|тесты]] }} | {{#ifeq: {{NAMESPACE}} | Модуль | [{{fullurl:{{FULLPAGENAME}}/песочница|action=edit}} создать] | [{{fullurl:{{FULLPAGENAME}}/песочница|action=edit&preload=Шаблон:Doc/предзагрузка-песочница}} создать] {{!}} [{{fullurl:{{FULLPAGENAME}}/песочница|action=edit&preload=Шаблон:Doc/зеркало}} зеркало] }} }})</small> или {{#ifeq: {{NAMESPACE}} | Модуль | [[w:ru:Модуль:Песочница|песочнице для модулей]] | своём [[w:ru:ВП:ЛП|личном пространстве]] }}.<br> }} }}{{#ifexist: {{FULLPAGENAME}}/doc | Пожалуйста, добавляйте категории на подстраницу [[/doc]].&#32;}}[[Special:PrefixIndex/{{FULLPAGENAME}}/|Подстраницы этого {{#ifeq: {{NAMESPACE}} | Модуль | модуля | шаблона }}]]. </div> }}</includeonly><noinclude>{{doc}}{{Указание авторства русскоязычной Википедии}}</noinclude> 8681561dd39a26e0c52106f8dd32bc9ac6e2081f Модуль:Unsubst 828 80 132 2021-09-24T10:34:57Z ruwiki>Grain of sand 0 + параметр $format Scribunto text/plain local checkType = require('libraryUtil').checkType local p = {} local BODY_PARAM = '$B' local specialParams = { ['$params'] = 'parameter list', ['$aliases'] = 'parameter aliases', ['$flags'] = 'flags', ['$format'] = 'date format', ['$B'] = 'template content' } function p.main(frame, body) -- If we are substing, this function returns a template invocation, and if -- not, it returns the template body. The template body can be specified in -- the body parameter, or in the template parameter defined in the -- BODY_PARAM variable. This function can be called from Lua or from -- #invoke. -- Return the template body if we aren't substing. if not mw.isSubsting() then if body ~= nil then return body elseif frame.args[BODY_PARAM] ~= nil then return frame.args[BODY_PARAM] else error(string.format( "no template content specified (use parameter '%s' from #invoke)", BODY_PARAM ), 2) end end -- Sanity check for the frame object. if type(frame) ~= 'table' or type(frame.getParent) ~= 'function' or not frame:getParent() then error( "argument #1 to 'main' must be a frame object with a parent " .. "frame available", 2 ) end -- Find the invocation name. local mTemplateInvocation = require('Module:Template invocation') local name = mTemplateInvocation.name(frame:getParent():getTitle()) -- Combine passed args with passed defaults local args = {} local format = frame.args['$format'] or 'j xg Y' if string.find( ','..(frame.args['$flags'] or '')..',', ',%s*override%s*,' ) then for k, v in pairs( frame:getParent().args ) do args[k] = v end for k, v in pairs( frame.args ) do if not specialParams[k] then if v == '__DATE__' then v = mw.getContentLanguage():formatDate( format ) end args[k] = v end end else for k, v in pairs( frame.args ) do if not specialParams[k] then if v == '__DATE__' then v = mw.getContentLanguage():formatDate( format ) end args[k] = v end end for k, v in pairs( frame:getParent().args ) do args[k] = v end end -- Trim parameters, if not specified otherwise if not string.find( ','..(frame.args['$flags'] or '')..',', ',%s*keep%-whitespace%s*,' ) then for k, v in pairs( args ) do args[k] = mw.ustring.match(v, '^%s*(.*)%s*$') or '' end end -- Pull information from parameter aliases local aliases = {} if frame.args['$aliases'] then local list = mw.text.split( frame.args['$aliases'], '%s*,%s*' ) for k, v in ipairs( list ) do local tmp = mw.text.split( v, '%s*>%s*' ) aliases[tonumber(mw.ustring.match(tmp[1], '^[1-9][0-9]*$')) or tmp[1]] = ((tonumber(mw.ustring.match(tmp[2], '^[1-9][0-9]*$'))) or tmp[2]) end end for k, v in pairs( aliases ) do if args[k] and ( not args[v] or args[v] == '' ) then args[v] = args[k] end args[k] = nil end -- Remove empty parameters, if specified if string.find( ','..(frame.args['$flags'] or '')..',', ',%s*remove%-empty%s*,' ) then local tmp = 0 for k, v in ipairs( args ) do if v ~= '' or ( args[k+1] and args[k+1] ~= '' ) or ( args[k+2] and args[k+2] ~= '' ) then tmp = k else break end end for k, v in pairs( args ) do if v == '' then if not (type(k) == 'number' and k < tmp) then args[k] = nil end end end end -- Order parameters if frame.args['$params'] then local params, tmp = mw.text.split( frame.args['$params'], '%s*,%s*' ), {} for k, v in ipairs(params) do v = tonumber(mw.ustring.match(v, '^[1-9][0-9]*$')) or v if args[v] then tmp[v], args[v] = args[v], nil end end for k, v in pairs(args) do tmp[k], args[k] = args[k], nil end args = tmp end return mTemplateInvocation.invocation(name, args) end p[''] = p.main -- For backwards compatibility return p 66516cd1b82c9c1f13ac5cc5b9a87e1c93242068 Модуль:Dates 828 281 723 2021-10-11T18:35:23Z ruwiki>Wikisaurus 0 параметр nolinks для отключения викификации даты в [[Модуль:Wikidata/date]] Scribunto text/plain --[[ В это модуле собраны функции, связанные с работой с датами. ]] local monthg = {'января', 'февраля', 'марта', 'апреля', 'мая', 'июня', 'июля', 'августа', "сентября", "октября", "ноября", "декабря"} local monthd = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} local function DecodeDate(d)-- Ч, М, Г, СЧ, СМ, СГ, хвост --дата: "%-?%d+"=год, "%d+%.%d+"=число месяца, "%d+%.%d+%.%-?%d+"=ЧМГ, -- потом в скобках м.б. переопределено для старого стиля начиная с числа local nd=d:match("^[%d.-]*"); local od=d:match("^[%d.-]*%s*%(%s*([%d.-]*)%s*%)"); local tail = d:match("^[%d.-]+%s*%(%s*[%d.-]+%s*%)%s*(%S.*)") or d:match("^[%d.-]+%s*([^%s%d].*)"); if nd:match('^%-?%d+$' ) then return nil, nil, tonumber(nd), nil, nil, od and tonumber(od:match("%-?%d+$")),tail else local j,m,y=nd:match("^(%d+)%.(%d+)%.?(%-?%d*)"); if j then if od then local oj, om, oy = od:match("^(%d+)%.?(%d*)%.?(%-?%d*)"); return j and tonumber(j), m and tonumber(m), y>'' and tonumber(y) or nil, oj and tonumber(oj), om>'' and tonumber(om) or nil, oy>'' and tonumber(oy) or nil, tail end return j and tonumber(j), m and tonumber(m), y>'' and tonumber(y) or nil, nil, nil, nil, tail else return nil end end end local function Diffy(d1,m1,y1,d0,m0,y0)--аналог Персона/Дата/Прошло лет return y1-y0 - ( y1*y0<=0 and 1 or 0 ) - ( (m1<m0 or m1==m0 and d1<d0) and 1 or 0 ) end local function Year0(y,t)-- аналог Год0 if y>0 then return table.concat{ '[[', tostring(y), ' год|', t and tostring(y)..'&nbsp;'..t or tostring(y), ']]' } else return table.concat{ '[[', tostring(-y), ' год до н. э.|', t and tostring(-y)..'&nbsp;'..t or tostring(-y), '&nbsp;до&nbsp;н.&nbsp;э.]]' } end end local function FormDate(j,m,y,oj,om,oy,mo)-- ~ Персона/Дата/Logic 4 if j then if not m then return "''формат неверен''" end if y then return string.format( '<span class="nowrap">%s<span style="display:none">(<span class="%s">%04i-%02i-%02i</span>)</span></span>', table.concat( oj and ( om and ( oy and {-- ДД ММММ ГГГГ ([[ДД ММММ]] [[ГГГГ]]) oj,'&nbsp;',monthg[om],'&nbsp;',oy, '</span> <span class="nowrap">([[', j, ' ', monthg[m],']] ',Year0(y),')' } or {-- ДД ММММ ([[ДД ММММ]]) [[ГГГГ]] oj,'&nbsp;',monthg[om],' ([[',j,'&nbsp;',monthg[m],']]) ',Year0(y) } ) or {-- ДД [[ДД ММММ|(ДД) ММММ]] [[ГГГГ]] oj,'&nbsp;[[',j,' ',monthg[m],'|','(',j,')&nbsp;',monthg[m],']] ',Year0(y) } ) or {'[[',j,'&nbsp;',monthg[m],']]&nbsp;',Year0(y)} ),--/table.concat ({['Рождения']='bday',['Смерти']='dday'})[mo] or '', y,m,j )--/string.format else return '<span class="nowrap">' .. table.concat( oj and ( om and {-- ДД ММММ ([[ДД ММММ]]) oj,'&nbsp;',monthg[om],' ([[',j,'&nbsp;',monthg[m],']])</span>' } or {-- ДД [[ДД ММММ|(ДД) ММММ]] oj,'&nbsp;[[',j,' ',monthg[m],'|','(',j,')&nbsp;',monthg[m],']]</span>' } ) or {'[[',j,'&nbsp;',monthg[m],']]</span>'} ) end else return y and string.format( '<span class="nowrap">%s<span style="display:none;">(<span class="bday">%04i</span>)</span></span>', Year0(y,'год'),y) or "''формат неверен''" end end local function GetDate(D)--dd.mm.-?yyyy или -?yyyy-mm-dd в три переменных d,m,y local d,m,y = d:match('^%s*(%d%d?)[/.]([01]?%d)[/.](%-?%d+)') if not d then y,m,d = D:match('^%s*(%-?%d+)[-\\]0*(1?%d)[-\\]0*(%d+)') end return tonumber(d),tonumber(m),tonumber(y) end local function Cmp(a,b)--Сравнивает две даты, результат соответственно -1, 0 или 1 local d1,m1,y1 = GetDate(a) local d2,m2,y2 = GetDate(b) return d1 and d2 and (--nil, если формат не опознан y1==y2 and ( m1==m2 and ( d1==d2 and 0 or d1<d2 and -1 or 1 ) or m1<m2 and -1 or 1 ) or y1<y2 and -1 or 1 ) end local function Yyyymmdd(r)--Переводит русскую дату в YYYY,MM,DD local d, m, y, M = mw.ustring.match(r, "^%s*(%d%d?)%s+([а-яА-Я]+)%s+(%d+)") if not m then return nil end m = mw.ustring.lower(m) --тупо перебор for i = 1, 12 do if m == monthg[i] then M = i break end end if not M then return nil end return tonumber(y), M, tonumber(d) end local p = {} p = { ifdate=function(f)-- Для шаблона "Если дата", имитирует старое поведение -- Аргументы передаются шаблону return f:getParent().args[ mw.ustring.match(frame.args[1],"^[ %d.%-−%()]*$") and 2 or 3 ] end; DecodeDate = DecodeDate; Diffy = Diffy; Year0 = Year0; GetDate = GetDate; Cmp = Cmp; Yyyymmdd = Yyyymmdd; diffy = function(f)-- принимает параметры #invoke в виде двух строк-дат local d1,m1,y1=DecodeDate(f.args[1]); local d0,m0,y0=DecodeDate(f.args[2]) return Diffy(d1,m1,y1,d0,m0,y0) end; monthg=function(f) return monthg[ f.args[1] or f:getParent().args[1] ] end;--realmonth persdate=function(f)-- Для шаблона Персона/Дата;{{#invoke:dates|persdate|nocat={{NAMESPACE}}}} local frame=f:getParent(); local catpref,mo,d,d2={['Рождения']='Родившиеся',['Смерти']='Умершие'}, frame.args[1],frame.args[2],frame.args[3] local cat, j,m,y,oj,om,oy,tail, j2,m2,y2, age = '' if d then j,m,y,oj,om,oy,tail=DecodeDate(d:gsub('−','-')); if not (j or y) then return (frame.args.nocat and d or d..'[[Category:Википедия:Статьи с ручной викификацией дат в карточке]]') end end; if d2 then j2,m2,y2 = DecodeDate(d2:gsub('−','-')); end; return table.concat{ FormDate(j,m,y,oj,om,oy,mo), ( (frame.args['nopersoncat'] or '')~='' or (f.args['nocat'] or '')~='' ) and '' or table.concat{ '[[Category:Персоналии по алфавиту]]', j and string.format('[[Category:%s %i %s]]',catpref[mo],j,monthg[m]) or '', y and string.format('[[Category:%s в %s]]',catpref[mo],y,Year0(y,'году')) or '' },--/table.concat внутр. (function(F)--возраст if not F then return '' end; local n=F(); return n and string.format(" (%i %s)%s", n, mw.getLanguage('ru'):plural(n,'год','года','лет'), n>150 and '[[Category:Википедия:Статьи о персоналиях с большим текущим возрастом]]' or '' ) or '' end)( ({ ['Рождения']=function() local now=os.date('*t'); if (not d2 or d2=='') and j and m and y then return Diffy(now.day,now.month,now.year,j,m,y) end end, ['Смерти']=function() return j and m and y and j2 and m2 and y2 and Diffy(j,m,y,j2,m2,y2); end, })[mo] ),--конец вызова функции возраста tail or '', cat }--/table.concat внеш. end; formdate=function(f) -- Формирует дату по 3--6 параметрам #invoke или шаблона --не использовать с пустыми аргументами if (f.args[1] or '')~='' and (f.args[2] or '')~='' or (f.args[3] or '')~='' then return FormDate(f.args[1],f.args[2],f.args[3],f.args[4],f.args[5],f.args[6],f.args['m']) else local tf=f:getParent(); return FormDate(tf.args[1],tf.args[2],tf.args[3],tf.args[4],tf.args[5],tf.args[6],tf.args['m']) end end; cmp=function(f)--Сравнивает две даты, результат соответственно -1, 0 или 1 return Cmp(f.args[1],f.args[2]) end; G2J=function(f)--перевод григорианских дат в юлианские, возврат DD.MM.YYYY --Не знает про 15 октября 1582 года, не работает до нашей эры и после ???99 года --Если есть второй аргумент, преобразует только ДО этой даты включительно --Если есть третий аргумент, результат форматирует под Персона/Дата local d,m,y=GetDate(f.args[1]) if f.args[2] and Cmp(f.args[1],f.args[2])==1 then return string.format("%i.%i.%i",d,m,y) end local shift=math.floor(y/100)-math.floor(y/400)-2 if d-shift>0 then return f.args[3] and string.format("%i.%i.%i (%i)",d,m,y,d-shift) or string.format("%i.%i.%i",d-shift,m,y) else if m==1 then return f.args[3] and string.format("%i.1.%i (%i.12.%i)",d,y,31+d-shift,y-1) or string.format("%i.12.%i",31+d-shift,y-1) elseif m==3 then return f.args[3] and string.format("%i.3.%i (%i.2)", d,y, (y%4==0 and 29 or 28)+d-shift-(y%100==0 and y%400~=0 and 1 or 0) ) or string.format("%i.2.%i", (y%4==0 and 29 or 28)+d-shift-(y%100==0 and y%400~=0 and 1 or 0) ,y) else return f.args[3] and string.format( "%i.%i.%i (%i.%i)", d,m,y, monthd[m-1]+d-shift,m-1 ) or string.format("%i.%i.%i",monthd[m-1]+d-shift,m-1,y) end end end; -- Переводит русскую дату в YYYY-MM-DD. Возвращает входное значение, если дата уже в этом формате yyyymmdd = function(f) local date, hourmin = f.args[1] if mw.ustring.match(date, "^%s*%d+\-%d+\-%d+") then return date end hourmin = mw.ustring.match(date, "%s+%d+:%d+$") local y, m, d = Yyyymmdd(date) if not y then return '<span class="error">Ошибка: некорректный формат даты.</span>' end return string.format('%4i-%02i-%02i', y, m, d) .. (hourmin or '') end } function table.val_to_str ( v ) if "string" == type( v ) then v = string.gsub( v, "\n", "\\n" ) if string.match( string.gsub(v,"[^'\"]",""), '^"+$' ) then return "'" .. v .. "'" end return '"' .. string.gsub(v,'"', '\\"' ) .. '"' else return "table" == type( v ) and table.tostring( v ) or tostring( v ) end end function table.key_to_str ( k ) if "string" == type( k ) and string.match( k, "^[_%a][_%a%d]*$" ) then return k else return "[" .. table.val_to_str( k ) .. "]" end end function table.tostring( tbl ) local result, done = {}, {} for k, v in ipairs( tbl ) do table.insert( result, table.val_to_str( v ) ) done[ k ] = true end for k, v in pairs( tbl ) do if not done[ k ] then table.insert( result, table.key_to_str( k ) .. "=" .. table.val_to_str( v ) ) end end return "{" .. table.concat( result, "," ) .. "}" end local function parseISO8601Date(str) local pattern = "(%-?%d+)%-(%d+)%-(%d+)T" local Y, M, D = mw.ustring.match( str, pattern ) return tonumber(Y), tonumber(M), tonumber(D) end local function parseISO8601Time(str) local pattern = "T(%d+):(%d+):(%d+)%Z" local H, M, S = mw.ustring.match( str, pattern) return tonumber(H), tonumber(M), tonumber(S) end local function parseISO8601Offset(str) if str:sub(-1)=="Z" then return 0,0 end -- ends with Z, Zulu time -- matches ±hh:mm, ±hhmm or ±hh; else returns nils local pattern = "([-+])(%d%d):?(%d?%d?)$" local sign, oh, om = mw.ustring.match( str, pattern) sign, oh, om = sign or "+", oh or "00", om or "00" return tonumber(sign .. oh), tonumber(sign .. om) end function p.parseISO8601(str) if 'table'==type(str) then if str.args and str.args[1] then str = '' .. str.args[1] else return 'unknown argument type: ' .. type( str ) .. ': ' .. table.tostring( str ) end end local Y,M,D = parseISO8601Date(str) local h,m,s = parseISO8601Time(str) local oh,om = parseISO8601Offset(str) return tonumber(os.time({year=Y, month=M, day=D, hour=(h+oh), min=(m+om), sec=s})) end local g2uBoundary1 = p.parseISO8601('1582-10-15T00:00:00Z') local g2uBoundary2 = p.parseISO8601('1700-03-12T00:00:00Z') local g2uBoundary3 = p.parseISO8601('1800-03-13T00:00:00Z') local g2uBoundary4 = p.parseISO8601('1900-03-14T00:00:00Z') local g2uBoundary5 = p.parseISO8601('1918-01-26T00:00:00Z') -- декрет Ленина -- Передаваемое время обязано быть по Григорианскому календарю (новому стилю) function p.formatWiki( time, infocardClass, categoryNamePrefix ) if 'table'==type( time ) then if time.args and time.args[1] then time = tonumber( time.args[1] ) else return 'unknown argument type: ' .. type( time ) .. ': ' .. table.tostring( time ) end end local t = os.date("*t", time) if time < g2uBoundary1 then -- выводим просто юлианский календарь. Задавать тут григорианский некорректно return p.formatWikiImpl( t, t, infocardClass, categoryNamePrefix ) end -- Специальные даты if t.year == 1700 and t.month == 3 and t.day == 11 then return p.formatWikiImpl( {year=1700, month=2, day=29}, t, infocardClass, categoryNamePrefix) end if t.year == 1800 and t.month == 3 and t.day == 12 then return p.formatWikiImpl( {year=1800, month=2, day=29}, t, infocardClass, categoryNamePrefix ) end if t.year == 1900 and t.month == 3 and t.day == 13 then return p.formatWikiImpl( {year=1900, month=2, day=29}, t, infocardClass, categoryNamePrefix ) end if g2uBoundary1 <= time and time < g2uBoundary2 then return p.formatWikiImpl( os.date("*t", time - 10 * 24 * 60 * 60), t, infocardClass, categoryNamePrefix ) end if g2uBoundary2 <= time and time < g2uBoundary3 then return p.formatWikiImpl( os.date("*t", time - 11 * 24 * 60 * 60), t, infocardClass, categoryNamePrefix ) end if g2uBoundary3 <= time and time < g2uBoundary4 then return p.formatWikiImpl( os.date("*t", time - 12 * 24 * 60 * 60), t, infocardClass, categoryNamePrefix ) end if g2uBoundary4 <= time and time < g2uBoundary5 then return p.formatWikiImpl( os.date("*t", time - 13 * 24 * 60 * 60), t, infocardClass, categoryNamePrefix ) end --только Григорианский календарь return p.formatWikiImpl( t, t, infocardClass, categoryNamePrefix ) end local function ternary ( cond , T , F ) if cond then return T else return F end end local nominativeMonthes = {'январь', 'февраль', 'март', 'апрель', 'май', 'июнь', 'июль', 'август', 'сентябрь', 'октябрь', 'ноябрь', 'декабрь'} local genitivusMonthes = {'января', 'февраля', 'марта', 'апреля', 'мая', 'июня', 'июля', 'августа', 'сентября', 'октября', 'ноября', 'декабря'} local function nominativeYear( year, nolinks ) if ( year >= 0 ) then return nolinks and year or '[[' .. year .. ' год|' .. year .. ']]' else return nolinks and ( 0 - year ) .. ' до н. э.' or '[[' .. ( 0 - year ) .. ' год до н. э.|' .. ( 0 - year ) .. ' до н. э.]]' end end local function inYear( year ) if ( year >= 0 ) then return '' .. year .. ' году' else return '' .. ( 0 - year) .. ' году до н. э.' end end function p.formatWikiImpl( t1, t2, infocardClass, categoryNamePrefix, leftBracket, rightBracket, nolinks ) local nd = t2.day; local nm = t2.month; local ny = t2.year; local od = ternary ( t1.day ~= t2.day , t1.day, nil ); local om = ternary ( t1.month ~= t2.month , t1.month, nil ); local oy = ternary ( t1.year ~= t2.year , t1.year, nil ); if leftBracket == nil then leftBracket = '(' end if rightBracket == nil then rightBracket = ')' end local JulianComment = function(s) return tostring(mw.html.create("abbr") :attr("title","по юлианскому календарю") :wikitext(s) :done()) end local template = (nd ~= nil and "1" or "") .. (nm ~= nil and "2" or "") .. (ny ~= nil and "3" or "") .. (od ~= nil and "4" or "") .. (om ~= nil and "5" or "") .. (oy ~= nil and "6" or "") local datePart = '<span class="nowrap">' if (template == "12") then datePart = datePart .. string.format( nolinks and "%d %s" or "[[%d %s]]", nd, genitivusMonthes[nm] ) elseif (template == "23") then datePart = datePart .. string.format( "%s %s", nominativeMonthes[nm], nominativeYear( ny, nolinks ) ) elseif (template == "3") then datePart = datePart .. nominativeYear( ny, nolinks ) elseif (template == "123") then datePart = datePart .. string.format( nolinks and "%d %s %s" or "[[%d %s]] %s", nd, genitivusMonthes[nm], nominativeYear( ny, nolinks ) ) elseif (template == "124") then if nolinks then datePart = datePart .. JulianComment(string.format( "%d", od ) ).. string.format( " " .. leftBracket .. "%d" .. rightBracket .. " %s", nd, genitivusMonthes[nm] ) else datePart = datePart .. JulianComment(string.format( "%d", od ) ).. string.format( " [[%d %s|" .. leftBracket .. "%d" .. rightBracket .. " %s]]", nd, genitivusMonthes[nm], nd, genitivusMonthes[nm] ) end elseif (template == "1234") then if nolinks then datePart = datePart .. JulianComment(string.format( "%d", od ) ).. string.format( " |" .. leftBracket .. "%d" .. rightBracket .. " %s %s", nd, genitivusMonthes[nm], nominativeYear( ny, nolinks ) ) else datePart = datePart .. JulianComment(string.format( "%d", od ) ).. string.format( " [[%d %s|" .. leftBracket .. "%d" .. rightBracket .. " %s]] %s", nd, genitivusMonthes[nm], nd, genitivusMonthes[nm], nominativeYear( ny, nolinks ) ) end elseif (template == "1245") then datePart = datePart .. JulianComment(string.format( "%d %s", od, genitivusMonthes[om] ) ).. string.format(" " .. leftBracket .. (nolinks and "%d %s" or "[[%d %s]]") .. rightBracket .. "", nd, genitivusMonthes[nm] ) elseif (template == "12345") then datePart = datePart .. JulianComment(string.format( "%d %s", od, genitivusMonthes[om] ) ).. string.format(" " .. leftBracket .. (nolinks and "%d %s" or "[[%d %s]]") .. rightBracket .. " %s", nd, genitivusMonthes[nm], nominativeYear( ny, nolinks ) ) elseif (template == "123456") then datePart = datePart .. JulianComment(string.format( "%d %s %d", od, genitivusMonthes[om], oy )) .. '</span> <span class="nowrap">' .. string.format(" " .. leftBracket .. (nolinks and "%d %s %s" or "[[%d %s]] %s") .. rightBracket , nd, genitivusMonthes[nm], nominativeYear( ny, nolinks ) ) else datePart = datePart .. 'формат неверен' end datePart = datePart .. '</span>' local infocardTemplate = (nd ~= nil and "1" or "") .. (nm ~= nil and "2" or "") .. (ny ~= nil and "3" or "") if infocardClass then if (infocardTemplate == "123") then datePart = datePart .. string.format('<span style="display:none">(<span class="%s">%04d-%02d-%02d</span>)</span>', infocardClass , ny , nm , nd ) elseif (infocardTemplate == "23") then datePart = datePart .. string.format('<span style="display:none">(<span class="%s">%04d-%02d</span>)</span>', infocardClass , ny , nm ) elseif (infocardTemplate == "3") then datePart = datePart .. string.format('<span style="display:none;">(<span class="%s">%04d</span>)</span>', infocardClass , ny ) end end if categoryNamePrefix then if ( nd ~= nil and nm ~= nil) then datePart = datePart .. '[[Category:' .. categoryNamePrefix .. ' ' .. nd .. ' ' .. genitivusMonthes[nm] .. ']]' end if ( ny ~= nil) then datePart = datePart .. '[[Category:' .. categoryNamePrefix .. ' в ' .. inYear( ny ) .. ']]' end end return datePart end return p 902bb6a9ef5ce12ad4cfa19f3d2c964d7e092df7 Шаблон:Орден Красного Знамени 10 289 739 2021-10-23T21:05:30Z ruwiki>Jack who built the house 0 оформление кода при помощи [[u:JWBTH/CP|скрипта]] wikitext text/x-wiki {{#switch: {{{тип|}}} | воинская часть = [[Файл:Order of Red Banner.svg|34px|link=Орден Красного Знамени|Орден Красного Знамени {{#if: {{{1|}}} |  — {{{1}}} }}]]{{#if: {{NAMESPACE}}{{{nocat|}}} || [[Категория:Воинские части, награждённые орденом Красного Знамени]] }} | город = [[Файл:Order of Red Banner.svg|34px|link=Орден Красного Знамени|Орден Красного Знамени{{#if: {{{1|}}} |  — {{{1}}} }}]]{{#if: {{NAMESPACE}}{{{nocat|}}} || [[Категория:Города, награждённые орденом Красного Знамени]] }} | регион = [[Файл:Order of Red Banner.svg|34px|link=Орден Красного Знамени|Орден Красного Знамени{{#if: {{{1|}}} |  — {{{1}}} }}]]{{#if: {{NAMESPACE}}{{{nocat|}}} || [[Категория:Регионы, награждённые орденом Красного Знамени]] }} | организация = [[Файл:Order of Red Banner.svg|34px|link=Орден Красного Знамени|Орден Красного Знамени{{#if: {{{1|}}} |  — {{{1}}} }}]]{{#if: {{NAMESPACE}}{{{nocat|}}} || [[Категория:Организации, награждённые орденом Красного Знамени]] }} | СМИ | сми = [[Файл:Order of Red Banner.svg|34px|link=Орден Красного Знамени|Орден Красного Знамени {{#if: {{{1|}}} | — {{{1}}} }}]]{{#if: {{NAMESPACE}}{{{nocat|}}} || [[Категория:СМИ, награждённые орденом Красного Знамени]] }} | корабль = [[Файл:Order of Red Banner.svg|34px|link=Орден Красного Знамени|Орден Красного Знамени{{#if: {{{1|}}} | — {{{1}}} }}]]{{#if: {{NAMESPACE}}{{{nocat|}}} || [[Категория:Корабли, награждённые орденом Красного Знамени]] }} | [[Файл:SU Order of the Red Banner ribbon.svg|40px|link=Орден Красного Знамени|Орден Красного Знамени {{#if: {{{1|}}} |  — {{{1}}} }}]]{{#if: {{NAMESPACE}}{{{nocat|}}} || [[Категория:Кавалеры ордена Красного Знамени]] }} }}<noinclude> {{doc}} </noinclude> a4b6026ef99495ca5077c93a9192ac2427bbb09e Шаблон:Doc 10 171 384 2021-10-24T00:40:31Z ruwiki>Jack who built the house 0 оформление кода при помощи [[u:JWBTH/CP|скрипта]] wikitext text/x-wiki <includeonly>{{doc/begin|{{SUBJECTSPACE}}:{{PAGENAME:{{{1|{{SUBJECTPAGENAME}}/doc}}}}}}} {{#if: {{{1|}}} | {{#ifexist: {{{1}}} | {{{{{1}}}|{{{2|}}}|{{{3|}}}|{{{4|}}}|{{{5|}}}}} | {{#ifexist: {{SUBJECTSPACE}}:{{{1}}} | {{{{{1}}}|{{{2|}}}|{{{3|}}}|{{{4|}}}|{{{5|}}}}} | {{Документировать|{{{1}}}}} }} }} | {{#ifexist: {{SUBJECTPAGENAME}}/doc | {{{{SUBJECTPAGENAME}}/doc}} | {{Документировать|{{SUBJECTPAGENAME}}/doc}} }} }} {{doc/end}}</includeonly><noinclude> {{doc}} </noinclude> 391c7f0f075319e6b3305557c55e98c581696c71 Шаблон:Карточка/блок с маркерами 10 156 354 2021-10-24T15:48:39Z ruwiki>Oleg Yunakov 0 Защитил страницу [[Шаблон:Карточка/блок с маркерами]]: критический шаблон или модуль: https://ru.wikipedia.org/w/index.php?title=Википедия:Установка_защиты&oldid=117401039#Шаблоны ([Редактирование=администраторы и инженеры] (бессрочно) [Переименование=администраторы и инженеры] (бессрочно)) wikitext text/x-wiki {{#invoke:Infobox/bulleted block|main}}<noinclude>{{doc}}</noinclude> 71e7755aa4fb1e445f008da13d6fa4212aea3c38 Шаблон:Орден Октябрьской Революции 10 294 749 2021-10-24T15:52:04Z ruwiki>Oleg Yunakov 0 Изменил настройки защиты для «[[Шаблон:Орден Октябрьской Революции]]»: критический шаблон или модуль: https://ru.wikipedia.org/w/index.php?title=Википедия:Установка_защиты&oldid=117401039#Шаблоны ([Редактирование=администраторы и инженеры] (бессрочно) [Переименование=администраторы и инженеры] (бессрочно)) wikitext text/x-wiki {{#switch: {{{тип|}}} | воинская часть = [[Файл:Order of the October Revolution.svg|45px|link=Орден Октябрьской Революции|Орден Октябрьской Революции {{#if: {{{1|}}}| — {{{1}}}}}]]{{#if:{{NAMESPACE}}{{{nocat|}}}||[[Категория:Воинские части, награждённые орденом Октябрьской Революции]]}} | город = [[Файл:Order of the October Revolution.svg|45px|link=Орден Октябрьской Революции|Орден Октябрьской Революции {{#if: {{{1|}}}| — {{{1}}}}}]]{{#if:{{NAMESPACE}}{{{nocat|}}}||[[Категория:Города, награждённые орденом Октябрьской Революции]]}} | регион = [[Файл:Order of the October Revolution.svg|45px|link=Орден Октябрьской Революции|Орден Октябрьской Революции {{#if: {{{1|}}}| — {{{1}}}}}]]{{#if:{{NAMESPACE}}{{{nocat|}}}||[[Категория:Регионы, награждённые орденом Октябрьской Революции]]}} | организация = [[Файл:Order of the October Revolution.svg|45px|link=Орден Октябрьской Революции|Орден Октябрьской Революции {{#if: {{{1|}}}| — {{{1}}}}}]]{{#if:{{NAMESPACE}}{{{nocat|}}}||[[Категория:Организации, награждённые орденом Октябрьской Революции]]}} | СМИ | сми = [[Файл:Order of the October Revolution.svg|45px|link=Орден Октябрьской Революции|Орден Октябрьской Революции {{#if: {{{1|}}}|— {{{1}}}}}]]{{#if:{{NAMESPACE}}{{{nocat|}}}||[[Категория:СМИ, награждённые орденом Октябрьской Революции]]}} | корабль = [[Файл:Order of the October Revolution.svg|45px|link=Орден Октябрьской Революции|Орден Октябрьской Революции {{#if: {{{1|}}}| — {{{1}}}}}]]{{#if:{{NAMESPACE}}{{{nocat|}}}||[[Категория:Корабли, награждённые орденом Октябрьской Революции]]}} | [[Файл:SU Order of the October Revolution ribbon.svg|40px|link=Орден Октябрьской Революции|Орден Октябрьской Революции {{#if: {{{1|}}}| — {{{1}}}}}]]{{#if:{{NAMESPACE}}{{{nocat|}}}||[[Категория:Кавалеры ордена Октябрьской Революции]]}} }}<noinclude> {{doc}} </noinclude> c58fd2bbb6f2eea7bf65e4206a596693f9307c98 Шаблон:Ряд/styles.css 10 291 743 2021-10-24T16:01:25Z ruwiki>Oleg Yunakov 0 Защитил страницу [[Шаблон:Ряд/styles.css]]: критический шаблон или модуль: https://ru.wikipedia.org/w/index.php?title=Википедия:Установка_защиты&oldid=117401039#Шаблоны + Было бы неплохо и документацию потом добавить ([Редактирование=администраторы и инженеры] (бессрочно) [Переименование=администраторы и инженеры] (бессрочно)) sanitized-css text/css .ts-Ряд { width: auto; border-collapse: collapse; } .ts-Ряд td { padding-right: 2px; padding-left: 2px; text-align: center; } .ts-Ряд td:first-child { padding-left: 0; text-align: left; } .ts-Ряд td:last-child { padding-right: 0; text-align:right; } .ts-Ряд.pull-left { } .ts-Ряд.pull-center { margin: 0 auto !important; } .ts-Ряд.pull-right { clear: right; margin: 0 0 0 auto !important; } .ts-Ряд.pull-justify { width: 100%; } body.skin-minerva .ts-Ряд { display: table; } body.skin-minerva .ts-Ряд td { padding: 2px; } body.skin-minerva .ts-Ряд:not(.pull-justify) { width: auto !important; } /* [[Категория:Шаблоны:Подстраницы CSS]] */ 2229c228f5137296027e241d85449ea3d3a02656 Шаблон:Ряд 10 290 741 2021-10-24T17:09:43Z ruwiki>Oleg Yunakov 0 Защитил страницу [[Шаблон:Ряд]]: критический шаблон или модуль: https://ru.wikipedia.org/w/index.php?title=Википедия:Установка_защиты&oldid=117401039#Шаблоны ([Редактирование=администраторы и инженеры] (бессрочно) [Переименование=администраторы и инженеры] (бессрочно)) wikitext text/x-wiki <templatestyles src="Шаблон:Ряд/styles.css" /><table role="presentation" class="infobox-inherit ts-Ряд {{#switch:{{{выровнять|}}} | влево = pull-left | вправо = pull-right | по ширине = pull-justify | #default = pull-center}}"><tr>{{ #if:{{{1|}}}|<td>{{{1}}}</td>}}{{ #if:{{{2|}}}|<td>{{{2}}}</td>}}{{ #if:{{{3|}}}|<td>{{{3}}}</td>}}{{ #if:{{{4|}}}|<td>{{{4}}}</td>}}{{ #if:{{{5|}}}|<td>{{{5}}}</td>}}{{ #if:{{{6|}}}|<td>{{{6}}}</td>}}{{ #if:{{{7|}}}|<td>{{{7}}}</td>}}{{ #if:{{{8|}}}|<td>{{{8}}}</td>}}{{ #if:{{{9|}}}|<td>{{{9}}}</td>}}{{ #if:{{{10|}}}|<td>{{{10}}}</td>}} </tr></table><noinclude>{{doc}}</noinclude> 387ead03289de2d203805d43b37873225d7eaa75 Шаблон:Ombox 10 20 424 2021-10-24T18:05:30Z ruwiki>Oleg Yunakov 0 Изменил настройки защиты для «[[Шаблон:Ombox]]»: критический шаблон или модуль: https://ru.wikipedia.org/w/index.php?title=Википедия:Установка_защиты&oldid=117401039#Шаблоны ([Редактирование=администраторы и инженеры] (бессрочно) [Переименование=администраторы и инженеры] (бессрочно)) wikitext text/x-wiki {{#invoke:Message box|ombox}}<noinclude> {{doc}}<!-- Add categories and interwikis to the /doc subpage, not here! --></noinclude> ab34435c5ebc29de589c9b059e88da5d0e6f16e4 Модуль:Infobox/bulleted block 828 159 360 2021-10-24T18:17:22Z ruwiki>Oleg Yunakov 0 Защитил страницу [[Модуль:Infobox/bulleted block]]: критический шаблон или модуль: https://ru.wikipedia.org/w/index.php?title=Википедия:Установка_защиты&oldid=117401039#Шаблоны ([Редактирование=администраторы и инженеры] (бессрочно) [Переименование=администраторы и инженеры] (бессрочно)) Scribunto text/plain local p = {} -- takes strings or nils; returns a string function makeText(frame, text, wikidata, from) if wikidata and wikidata ~= ''then return frame:expandTemplate{title='Wikidata', args={wikidata, text or '', from=from or ''}} else return text or '' end end -- from [[ru:Модуль:Infobox]] local function maxNumber ( args ) local maxNumber = 0 for argName, _ in pairs(args) do local argNumber = mw.ustring.match(argName, '^[^0-9]+([0-9]+)$') if argNumber and tonumber(argNumber) > maxNumber then maxNumber = tonumber(argNumber) end end return maxNumber end function p.main(frame) local args = frame:getParent().args local maxNumberArgs = maxNumber(args) local texts = {} for i = 1, maxNumberArgs do if args['текст' .. i] then texts[i] = makeText(frame, args['текст' .. i], args['викиданные' .. i], args['from']) end end local textsAreEmpty = true for i = 1, maxNumberArgs do if texts[i] and texts[i] ~= '' then textsAreEmpty = false end end local results = {} if not textsAreEmpty and args['подзаголовок'] and args['подзаголовок'] ~= '' then results['текст1'] = args['подзаголовок'] results['стиль_текста1'] = 'padding-bottom:0; border-bottom:0; text-align:left; font-weight:bold;' end local mainText = makeText(frame, args['текст'], args['викиданные'], args['from']) if mainText == '' and args['метка'] and args['метка'] ~= '' and not textsAreEmpty then mainText = '&nbsp;' end if mainText and mainText ~= '' then results['метка2'] = args['метка'] results['стиль_метки2'] = 'padding-bottom:0; border-bottom:0;' results['текст2'] = mainText results['стиль_текста2'] = 'padding-bottom:0; border-bottom:0;' end for i = 1, maxNumberArgs do if texts[i] and texts[i] ~= '' then results['метка' .. (i+2)] = '&nbsp;•&nbsp;' .. (args['метка' .. i] or '') results['текст' .. (i+2)] = texts[i] local last = true for j = i+1, maxNumberArgs do if texts[j] and texts[j] ~= '' then last = false end end if last then results['стиль_метки' .. (i+2)] = 'font-weight:normal; padding-top:0; border-top:0;' results['стиль_текста' .. (i+2)] = 'padding-top:0; border-top:0;' else results['стиль_метки' .. (i+2)] = 'font-weight:normal; padding-bottom:0; border-bottom:0; padding-top:0; border-top:0;' results['стиль_текста' .. (i+2)] = 'padding-bottom:0; border-bottom:0; padding-top:0; border-top:0;' end end end return frame:expandTemplate{title='Карточка/блок', args=results} end return p 856b97606e1f2809c940e384f6fe71a575ca019e Шаблон:Tlp 10 217 482 2021-10-24T18:18:30Z ruwiki>Oleg Yunakov 0 Изменил настройки защиты для «[[Шаблон:Tlp]]»: критический шаблон или модуль: https://ru.wikipedia.org/w/index.php?title=Википедия:Установка_защиты&oldid=117401039#Шаблоны ([Редактирование=администраторы и инженеры] (бессрочно) [Переименование=администраторы и инженеры] (бессрочно)) wikitext text/x-wiki {{{{{|safesubst:}}}#invoke: Template call code | withParams | _link = 1 }}<noinclude>{{doc}}</noinclude> 36c309cb28ccf0901f4fff46cbd35cdabcf00661 Шаблон:Tag 10 72 116 2021-10-26T15:10:39Z ruwiki>Jack who built the house 0 стилизация на основе [[Модуль:Template call code/styles.css]] wikitext text/x-wiki {{#ifeq: {{{style|}}} | regular | <templatestyles src="Модуль:Template call code/styles.css" /> }}<{{#ifeq: {{{style|}}} | regular | span | code }} class="{{#ifeq: {{{wrap|}}} | yes | wrap | nowrap }}" style="{{#switch: {{{style|}}} | plain = border:none; background:transparent; | regular = | {{{style|}}} }}"><!-- Opening tag -->{{#switch: {{#if: {{{2|}}} | {{{2|}}} | pair }} |c|close = |s|single |o|open |p|pair = {{#ifeq: {{{1|tag}}} | !-- | {{#ifeq: {{{style|}}} | regular | <span class="ts-templateCallCode-weak">&lt;!--</span> | &lt;!-- }} | {{#ifeq: {{{style|}}} | regular | <span class="ts-templateCallCode-weak">&lt;</span> | &lt; }}{{{1|tag}}}{{#if: {{{params|{{{p|}}}}}} | &#32;{{{params|{{{p|}}}}}} }} }} }}<!-- Content between tags -->{{#switch: {{#if: {{{2|}}} | {{{2|}}} | pair }} |c|close = {{{content|{{{c|}}}}}} |s|single = &#32;{{#ifeq: {{{style|}}} | regular | <span class="ts-templateCallCode-weak">/&gt;</span> | /&gt; }} |o|open = {{#ifeq: {{{style|}}} | regular | <span class="ts-templateCallCode-weak">&gt;</span> | &gt; }}{{{content|{{{c|}}}}}} |p|pair = {{#ifeq: {{{1|tag}}} | !-- || {{#ifeq: {{{style|}}} | regular | <span class="ts-templateCallCode-weak">&gt;</span> | &gt; }} }}{{{content|{{{c|}}}}}} }}<!-- Closing tag -->{{#switch: {{#if: {{{2|}}} | {{{2|}}} | pair }} |s|single |o|open = |c|close |p|pair = {{#ifeq: {{{1|tag}}} | !-- | {{#ifeq: {{{style|}}} | regular | <span class="ts-templateCallCode-weak">--&gt;</span> | --&gt; }} | {{#ifeq: {{{style|}}} | regular | <span class="ts-templateCallCode-weak">&lt;/</span>{{{1|tag}}}<span class="ts-templateCallCode-weak">&gt;</span> | &lt;/{{{1|tag}}}&gt; }} }} }}<!-- --></{{#ifeq: {{{style|}}} | regular | span | code }}><noinclude>{{doc}}</noinclude> 2818843691a5275eaf013ee7cc1ac4b87c34f392 Модуль:Template call code 828 126 294 2021-10-26T19:03:06Z ruwiki>Jack who built the house 0 -избыточный код Scribunto text/plain local getArgs = require('Module:Arguments').getArgs local ru = mw.language.new('ru') local p = {} -- Используется для того, чтобы можно было удалять элементы из таблицы local function copy(other) local res = {} for k, v in pairs(other) do res[k] = v end return res end local function makeInvokeFunc(funcName, flags) return function (frame) local args = copy(getArgs(frame, { trim = false, removeBlanks = false })) return p[funcName](args, flags) end end --предотвращает обработку вики-текста в отображении образца local function processText(str, nowiki) local res = str if nowiki then str = mw.text.unstripNoWiki(str) str = string.gsub(str, '%[', '&#91;') str = string.gsub(str, '%]', '&#93;') str = string.gsub(str, '<', '&lt;') str = string.gsub(str, '>', '&gt;') str = string.gsub(str, '{', '&#123;') str = string.gsub(str, '|', '&#124;') str = string.gsub(str, '}', '&#125;') str = string.gsub(str, '\'', '&#39;') str = string.gsub(str, '"', '&quot;') str = string.gsub(str, '(://)', '<span>%1</span>') end return str end local function addParams(args, params) local text, equals_pos, param, value = '', 0, '', '' local function addPipe() if params.spaced then text = text .. ' ' end text = text .. '<span class="' if not params.spaced then text = text .. ' ts-templateCallCode-pipe' end if not params.black then text = text .. ' ts-templateCallCode-weak' end -- &#124;, чтобы не трактовалось как разделитель ячеек в таблицах text = text .. '">&#124;</span>' end local beforeParam = '<span class="ts-templateCallCode-param">' local afterParam = '</span>' for k, v in pairs(args) do if type(k) == 'number' then -- Неименованные параметры if k >= params.from then equals_pos = v:find('=') if equals_pos and v:find('{{=}}') == equals_pos - 2 then equals_pos = nil end if equals_pos then -- Содержащие «=» преобразуем в именованные param = v:sub(1, equals_pos - 1) value = v:sub(equals_pos + 1) addPipe() text = text .. beforeParam .. processText(param, params.nowiki) .. '=' .. processText(value, params.nowiki) .. afterParam else -- Истинно неименованные addPipe() local paramValue = processText(v, params.nowiki) if #paramValue ~= 0 then text = text .. beforeParam .. paramValue .. afterParam end end end elseif not k:find('^_') then -- Именованные параметры, исключая модификаторы внешнего вида addPipe() text = text .. beforeParam .. processText(k, params.nowiki) .. '=' .. processText(v, params.nowiki) .. afterParam end end return text end function p._main(args, flags) local name = args[1] table.remove(args, 1) -- Вещи типа «=» в первом параметре if not name then for k, v in pairs(args) do if not k:find('^_') then name = k .. '=' .. v args[k] = nil break end end end local optpText if not flags.withoutParams then if name then local spanOffset = mw.ustring.find(name, '<span') -- След использования шаблона optp if spanOffset then optpText = mw.ustring.sub(name, spanOffset) name = mw.ustring.sub(name, 1, spanOffset - 1) end end end local yesno = require('Module:Yesno') local nolink, subst, podst, global, nav, noRedirect, ucFirst, black, nobr local tag, style, comment, lang, sister, global, textInPlaceOfName, namePrefix, prefix, postfix, nowiki local spaced, from if flags.withoutParams then for i, v in ipairs(args) do if v == 'nl' or v == 'nolink' then noLink = true elseif v == 's' then subst = true elseif v == 'п' then podst = true elseif v == 'g' then global = true elseif v == 'nav' then nav = true elseif v == 'noredir' then noRedirect = true elseif v == 'u' then ucFirst = true elseif v == 'b' then black = true elseif v == 'nobr' then nobr = true end end tag = args.tag or 'span' style = args.style comment = args.comment lang = args.lang sister = args.sister textInPlaceOfName = args.text namePrefix = args.nameprefix prefix = args.prefix postfix = args.postfix nowiki = args.nowiki else noLink = yesno(args._nolink or args._nl, false) or not yesno(args._link, false) subst = yesno(args._s, false) podst = yesno(args['_п'], false) global = yesno(args._g, false) nav = yesno(args._nav, false) noRedirect = yesno(args._noredir, false) ucFirst = yesno(args._u, false) black = yesno(args._b, false) nobr = yesno(args._nobr, false) tag = args._tag or 'span' style = args._style comment = args._comment lang = args._lang sister = args._sister textInPlaceOfName = args._text namePrefix = args._nameprefix prefix = args._prefix postfix = args._postfix nowiki = args._nowiki spaced = yesno(args._spaced, false) from = (tonumber(args._from) or 2) - 1 end global = global or name and mw.ustring.sub(name, 1, 1) == ':' black = black or tag ~= 'span' if textInPlaceOfName == '' then textInPlaceOfName = nil end if comment == '' then comment = nil end if lang == '' then lang = nil end if sister == '' then sister = nil end if namePrefix == '' then namePrefix = nil end if name then local trimmedName = mw.text.trim(name) if ru:lc(mw.ustring.sub(trimmedName, 1, 6)) == 'subst:' then subst = true name = mw.ustring.sub(trimmedName, 7) end if ru:lc(mw.ustring.sub(trimmedName, 1, 6)) == 'подст:' then podst = true name = mw.ustring.sub(trimmedName, 7) end end if subst then namePrefix = 'subst:' elseif podst then namePrefix = 'подст:' end local currentTitle = mw.title.getCurrentTitle() -- При опущенном первом параметре берём имя шаблона из названия страницы if name == '' or not name then local currentTitleRoot = currentTitle.rootText if not ucFirst and ( ( ru:uc(currentTitleRoot) ~= currentTitleRoot and -- Книга:Литературное наследство, TranslateDate not mw.ustring.match(currentTitleRoot, '^[А-Яа-яA-Za-z]+:?[А-ЯA-Z]') ) or #currentTitleRoot == 1 ) then name = ru:lcfirst(currentTitleRoot) else name = currentTitleRoot end end -- Начинаем собирать код local linkBody, titleObject, linkBegin, linkDivider, linkEnd local prefixes = {} if lang then table.insert(prefixes, lang) end if sister then table.insert(prefixes, sister) end linkBody = table.concat(prefixes, ':') if #linkBody ~= 0 then linkBody = ':' .. linkBody end if mw.ustring.sub(name, 1, 1) ~= ':' then linkBody = linkBody .. ':' end if not global then linkBody = linkBody .. 'Template:' end linkBody = linkBody .. name titleObject = mw.title.new(linkBody) local noLink = noLink or currentTitle == titleObject if not noLink then if not noRedirect or ( noRedirect and not lang and not sister and not titleObject.exists ) then linkBegin = '[[' linkEnd = ']]' linkDivider = '|' else linkBegin = '[' linkEnd = ']' linkDivider = ' ' linkBody = titleObject:fullUrl('redirect=no') end end local text = '' if tag then text = text .. '<' .. tag .. ' class="ts-templateCallCode' if nobr then text = text .. ' nowrap' end text = text .. '"' if style then text = text .. ' style="' .. style .. '"' end text = text .. '>' end if prefix then text = text .. processText(prefix, nowiki) end text = text .. '<span class="' if not spaced then text = text .. ' ts-templateCallCode-opening' end if not black then text = text .. ' ts-templateCallCode-weak' end text = text .. '">{{' if namePrefix then text = text .. namePrefix end text = text .. '</span>' if nav and currentTitle == titleObject then text = text .. '\'\'\'' end text = text .. '<span class="ts-templateCallCode-templateName" data-navboxnavigation-link="0">' local commentedLabel if comment then -- https://phabricator.wikimedia.org/T200704 -- commentedLabel = mw.getCurrentFrame():expandTemplate({title = 'comment', args = {(textInPlaceOfName or name), comment}}) commentedLabel = '<span class="commentedText" title="' .. comment .. '" style="border-bottom: 1px dotted; cursor: help;">' .. (textInPlaceOfName or name) .. '</span>' end local label = (commentedLabel or textInPlaceOfName or name) if not noLink then if noRedirect then text = text .. '<span class="plainlinks">' end text = text .. linkBegin .. linkBody .. linkDivider .. label .. linkEnd if noRedirect then text = text .. '</span>' end else text = text .. label end text = text .. '</span>' if nav and currentTitle == titleObject then text = text .. '\'\'\'' end if not flags.withoutParams then if optpText then text = text .. optpText end text = text .. addParams(args, { spaced = spaced, black = black, nowiki = nowiki, from = from }) if spaced then text = text .. ' ' end end text = text .. '<span class="' if not spaced then text = text .. ' ts-templateCallCode-closing' end if not black then text = text .. ' ts-templateCallCode-weak' end text = text .. '">}}</span>' if postfix then text = text .. processText(postfix, nowiki) end if tag then text = text .. '</' .. tag .. '>' end local ts = mw.getCurrentFrame():extensionTag{ name = 'templatestyles', args = { src = 'Модуль:Template call code/styles.css' } } return ts .. text end function p._onlyParams(args) local yesno = require('Module:Yesno') return addParams(args, { spaced = yesno(args._spaced, false), black = true, nowiki = yesno(args._nowiki, false), from = 1 }) end p.withoutParams = makeInvokeFunc('_main', {withoutParams = true}) p.withParams = makeInvokeFunc('_main', {withoutParams = false}) p.onlyParams = makeInvokeFunc('_onlyParams') return p c4cde66869b509219e9bf629a766ce30ad0bdf97 Шаблон:TOC right 10 194 434 2021-10-27T21:30:30Z ruwiki>Grain of sand 0 TOC limit через TS wikitext text/x-wiki <templatestyles src="Шаблон:TOC right/styles.css" /><!-- -->{{#if: {{{limit|}}} | <templatestyles src="Шаблон:TOC limit/styles.css" /> }}<!-- --><div class="ts-TOC_right {{#if: {{{limit|}}} | ts-TOC_limit-{{{limit|}}} }}" style="{{#if: {{{clear|}}} | clear:{{{clear|}}}; }}{{#if: {{{width|{{{1|}}}}}} | width:{{{width|{{{1|}}}}}}; }}{{#if: {{{max-width|}}} | max-width: {{{max-width|}}}; }}">__TOC__</div><noinclude> {{doc}} </noinclude> 84311f23c6ae2f952b4496c710868089ed317e45 Шаблон:C 10 297 755 2021-11-05T11:44:04Z ruwiki>GAndy 0 Изменил настройки защиты для «[[Шаблон:C]]»: понижение защиты согласно количеству включений (больше 2000, меньше 5000) ([Редактирование=только автоподтверждённые] (бессрочно) [Переименование=только автоподтверждённые] (бессрочно)) wikitext text/x-wiki {{#switch: {{{2}}} | Р = {{{к|к}}}атегории | Д = {{{к|к}}}атегории | В = {{{к|к}}}атегорию | Т = {{{к|к}}}атегорией | П = {{{к|к}}}атегории | ю = {{{к|к}}}атегорию | ей | й = {{{к|к}}}атегорией | и = {{{к|к}}}атегории | {{{к|к}}}атегория }} «[[:Категория:{{{1}}}|{{вложенные кавычки|{{{1}}}}}]]»<noinclude>{{doc}}</noinclude> 29dc241d0737db87ea05ae164b21b3bdc0da3f83 Шаблон:Ifempty 10 198 442 2021-11-07T14:03:01Z ruwiki>Grain of sand 0 на модуль wikitext text/x-wiki <includeonly>{{#invoke:Ifempty|main}}</includeonly><noinclude> {{Doc}} <!-- Add categories and interwikis to the /doc subpage, not here! Добавляйте категории и интервики на подстраницу документации, а не сюда --> </noinclude> c14bef2160201468f96da309e565ff2fde725cf5 Модуль:Ifempty 828 85 144 2021-11-08T15:29:31Z ruwiki>Ping08 0 Изменил настройки защиты для «[[Модуль:Ifempty]]»: критический шаблон или модуль: более 125000 включений ([Редактирование=администраторы и инженеры] (бессрочно) [Переименование=администраторы и инженеры] (бессрочно)) Scribunto text/plain local p = {} local getArgs = require('Module:Arguments').getArgs function p.main(frame) local args = getArgs(frame, {removeBlanks = false}) local before = args['до'] local after = args['после'] for i, v in ipairs(args) do if v ~= '' then return (before or '') .. v .. (after or '') end end end return p 875e8c9f03fb4cc02d80271ad3aaab13a9bcea86 Модуль:Template call code/styles.css 828 128 298 2021-11-15T10:35:51Z ruwiki>Jack who built the house 0 поддержка [[t:optp]] (например, на [[Модуль:Unsubst/doc]]) sanitized-css text/css .ts-templateCallCode-weak { color: #72777d; } .ts-templateCallCode-pipe { margin: 0 2px; } .ts-templateCallCode-pipe + .ts-templateCallCode-pipe, /* Template:Optp */ .ts-templateCallCode-pipe + .ts-templateCallCode-param > .ts-templateCallCode-weak:first-child > .ts-templateCallCode-pipe:first-child { margin-left: 0; } .ts-templateCallCode-param + .ts-templateCallCode-closing { margin-left: 2px; } span.ts-templateCallCode > .ts-templateCallCode-templateName a { /* Решение из https://ru.wikipedia.org/wiki/Шаблон:Фиттс */ padding: 0 0.5em !important; /* Перезаписываем стиль для .plainlinks a.external */ position: relative; margin: -0.5em; } /* [[Категория:Шаблоны:Подстраницы CSS]] */ b3ed166240cf28c48a58b8d992794b753b2c6ef5 Шаблон:Lang-en 10 282 725 2022-01-02T12:52:08Z ruwiki>Abiyoyo 0 замена редиректа прямым включением wikitext text/x-wiki <nowiki />[[английский язык|англ.]]&nbsp;{{lang-en2|{{{1}}}}}<noinclude> {{doc|Lang/doc}} </noinclude> 6fcc1d4dc63f133033671bf27e48a6e701e126cb Модуль:Wikidata/number 828 186 416 2022-01-11T01:52:22Z ruwiki>Putnik 0 для очень старых дат timestamp меньше 0, и это ломало логику Scribunto text/plain local p = {} function p.formatVisualMagnitude ( context, options ) if ( not context ) then error( 'context not specified' ); end; if ( not options ) then error( 'options not specified' ); end; min = context.selectClaims( options, 'P1215[P1227:Q76596947][rank:normal,rank:preferred]' ) max = context.selectClaims( options, 'P1215[P1227:Q76596417][rank:normal,rank:preferred]' ) if ( not min or not max) then -- показываем как обычно return context.formatPropertyDefault( context, options ) end -- показываем Vmin-Vmax для переменной звезды local lang = mw.language.getContentLanguage(); for _, claim1 in ipairs(min) do for _, claim2 in ipairs(max) do return lang:formatNum(tonumber(claim1.mainsnak.datavalue.value.amount)) .. ' − ' .. lang:formatNum(tonumber(claim2.mainsnak.datavalue.value.amount)) end end end function p.formatColorIndex( context, options ) if ( not context ) then error( 'context not specified' ); end; if ( not options ) then error( 'options not specified' ); end; if ( options.property ) then -- Пролучаем все claims независимо от ранга claims = context.selectClaims( options, options.property .. '[rank:normal,rank:preferred]' ); end if ( claims ) then return context.formatPropertyDefault( context, options ) end -- Вычисляем B-V либо U-B из P1215 b = context.selectClaims( options, 'P1215[P1227:Q6746395][rank:normal,rank:preferred]' ) if ( not b ) then return end if string.find( options.property, 'Q17773035' ) then m1 = context.selectClaims( options, 'P1215[P1227:Q15977921][rank:normal,rank:preferred]' ) m2 = b if ( not m1 ) then return end else m1 = b m2 = context.selectClaims( options, 'P1215[P1227:Q4892529][rank:normal,rank:preferred]' ) if ( not m2 ) then return end end for _, claim1 in ipairs(m1) do for _, claim2 in ipairs(m2) do newClaim = { mainsnak = { snaktype = 'value', datavalue = { type = 'quantity', value = { unit = '1', amount = claim1.mainsnak.datavalue.value.amount - claim2.mainsnak.datavalue.value.amount }}}} return context.formatStatementDefault( context, options, newClaim ) end end end function p.formatPropertyWithMostRecentClaimAndIndicator( context, options ) if ( not context ) then error( 'context not specified' ); end; if ( not options ) then error( 'options not specified' ); end; if ( not options.entity ) then error( 'options.entity missing' ); end; local claims; if options.property then -- Пролучаем все claims независимо от ранга claims = context.selectClaims( options, options.property .. '[rank:normal,rank:preferred]' ); end if claims == nil then return '' end -- Ищем claim с максимальным значением P585 и форматируем его в out local maxTimestamp = nil; local mostRecentClaim; for i, claim in ipairs(claims) do if (claim.qualifiers and claim.qualifiers.P585) then -- обрабатываем только claims с указанным P585 local timestamp = context.parseTimeFromSnak( claim.qualifiers.P585[1] ); if timestamp ~= nil and ( maxTimestamp == nil or maxTimestamp < timestamp ) then maxTimestamp = timestamp; mostRecentClaim = claim end end end if (not mostRecentClaim) then -- нет ни одного claim с указанным P585 return context.formatPropertyDefault( context, options ) end local out = context.formatStatement( options, mostRecentClaim ) if out ~= '' then -- Ищем claim со значением P585 сразу после максимального и запоминаем его в secondMostRecentValue local secondMostRecentTimestamp = 0; local secondMostRecentValue = 0; for i, claim in ipairs(claims) do if (claim.qualifiers and claim.qualifiers.P585) then -- обрабатываем только claims с указанным P585 local timestamp = context.parseTimeFromSnak( claim.qualifiers.P585[1] ) if (timestamp ~= nil and secondMostRecentTimestamp < timestamp and maxTimestamp > timestamp) then secondMostRecentTimestamp = timestamp secondMostRecentValue = tonumber( claim.mainsnak.datavalue.value.amount ) end end end if (secondMostRecentValue ~= 0) then -- если предыдущее значение нашлось if (secondMostRecentValue < tonumber( mostRecentClaim.mainsnak.datavalue.value.amount )) then out = '<span style="color: #0c0; font-size: larger;">▲</span>' .. out else out = '<span style="color: red; font-size: larger;">▼</span>' .. out end end if options.before then out = options.before .. out end if options.after then out = out .. options.after end end return out end function p.formatQuantityWithDateClaim( context, options, statement ) local snak = context.formatSnak( options, statement.mainsnak ) if not snak then return '' end --Date if ( statement.qualifiers and statement.qualifiers.P585 ) then snak = snak .. ' (' .. context.formatSnak( options, statement.qualifiers.P585[1] ) .. ')' end --References if ( options.references ) then snak = snak .. context.formatRefs( options, statement ); end return snak end function p.formatDMS( context, options, value ) if not value.amount then return value end if options and options.unit == '-' then return value.amount end local prefix = "+" if tonumber( value.amount ) < 0 then prefix = "−" end return p.formatAngle ( math.abs( tonumber( value.amount ) ), string.len( value.amount ) - string.find( value.amount, '.', 1, true ) - 5, prefix .. "%s° %02d′ %s″") end function p.formatRA( context, options, value ) if not value.amount then return value end if options and options.unit == '-' then return value.amount end return p.formatAngle (tonumber( value.amount ) / 15, string.len( value.amount ) - string.find( value.amount, '.', 1, true ) - 4, "%s<sup>ч</sup> %02d<sup>м</sup> %s<sup>с</sup>") end function p.formatAngle ( angle, sig, format ) local d, angle = math.modf( angle ) local m, angle = math.modf( angle * 60 ) local mult = 10 ^ sig; local s = math.floor( angle * 60 * mult + 0.5 ) / mult; local lang = mw.language.getContentLanguage(); return string.format( format, d, m, lang:formatNum( s ) ) end return p 2f96549583b299597b7f95fbceeddad31ccee753 Шаблон:Подстраницы шаблона Карточка 10 221 490 2022-01-19T19:49:51Z ruwiki>WindEwriX 0 fix wikitext text/x-wiki {{Навигационная таблица |имя = Подстраницы шаблона Карточка |state = {{{state|}}} |класс_списков = hlist hlist-items-nowrap |заголовок = Подстраницы шаблона {{tnav|Карточка}} |tracking = <includeonly>no</includeonly> |группа1 = {{!}}вверху= |список1 = * {{tnav|карточка/название}} (заголовок без уточнения) * {{tnav|карточка/имя}} (заголовок в обратном порядке и без уточнения) |группа2 = {{!}}вверху2= |список2 = * {{tnav|карточка/оригинал названия}} (свойство [[d:P:P1705|P1705]]) * {{tnav|карточка/оригинал названия произведения}} (свойство [[d:P:P1476|P1476]]) * {{tnav|карточка/официальное название}} (свойство [[d:P:P1448|P1448]]) * {{tnav|карточка/оригинал имени}} (свойство [[d:P:P1559|P1559]]) |группа3 = Разное |список3 = * {{tnav|карточка/изображение}} * {{tnav|карточка/Изображение рядом}} * {{tnav|карточка/флаг и герб}} (свойства [[d:p:P41|P41]] и [[d:p:P94|P94]]) * {{tnav|карточка/медали}} (свойство [[d:p:P166|P166]]) * {{tnav|карточка/хронология}} (свойства [[d:p:P155|P155]] и [[d:p:P156|P156]]) * {{tnav|карточка/период}} (свойства [[d:p:P580|P580]] и [[d:p:P582|P582]]) * {{tnav|карточка/коды в каталогах}} (свойство [[d:p:P528|P528]]) * {{tnav|карточка/блок}} * {{tnav|карточка/блок с маркерами}} |группа4 = {{!}}внизу= |список4 = * {{tnav|карточка/Викиданные}} * {{tnav|карточка/Викисклад}} (свойство [[d:P:P373|P373]]) * {{tnav|карточка/Викитека}} * {{tnav|карточка/Викиучебник}} * {{tnav|карточка/Викицитатник}} |класс_внизу = hlist |внизу = ; См. также : [[Википедия:Шаблоны-карточки]] : [[:Категория:Шаблоны:Для шаблонов-карточек]] }}<noinclude> [[Категория:Навигационные шаблоны:Для шаблонов]] </noinclude> f7c3cb19df3f1a23fdde48e58f259bb1f952d0ed Шаблон:Карточка 10 129 300 2022-04-03T23:49:38Z ruwiki>Putnik 0 пробуем красить каждую карточку на странице отдельно, без перекрытия стилей; надеюсь, комбинация имя+вверху0+вверху+вверху2 достаточно уникальна и не вызовет ошибок wikitext text/x-wiki {{#if:{{{имя|}}}|{{#ifeq:{{{имя|}}}|-||{{#if:{{{цвет|}}}|{{#tag:templatestyles| |wrapper=.infobox-{{#invoke:Hash|main|{{{имя}}} {{{вверху0|}}} {{{вверху|}}} {{{вверху2|}}}}} |src=Шаблон:Цвет/{{{цвет|}}}.css }}}}}}}}<table class="infobox infobox-{{#invoke:Hash|main|{{{имя}}} {{{вверху0|}}} {{{вверху|}}} {{{вверху2|}}}}} {{{класс_тела|}}}" style="{{{стиль_тела|}}}" {{#if:{{{имя|}}}|{{#ifeq:{{{имя|}}}|-||data-name="{{{имя}}}"}}}} {{#if:{{{from|}}}|{{#ifeq:{{{from|}}}|-||data-from="{{{from}}}"}}}}><!-- Вверху0 -->{{#if:{{{вверху0|}}}|<tr><td colspan="2" class="{{{класс_вверху0|}}}" style="text-align:center; {{{стиль_вверху0|}}}">{{{вверху0}}}</td></tr>}}<!-- Вверху -->{{#if:{{{вверху|}}}|<tr><th colspan="2" scope="colgroup" class="infobox-above {{{класс_вверху|}}}" style="{{{стиль_вверху|}}}">{{{вверху}}}</th></tr>}}<!-- Вверху2 -->{{#if:{{{вверху2|}}}|<tr><td colspan="2" class="{{{класс_вверху2|}}}" style="text-align:center; {{{стиль_вверху2|}}}">{{{вверху2}}}</td></tr>}}<!-- Вверху3 -->{{#if:{{{вверху3|}}}|<tr><td colspan="2" class="{{{класс_вверху3|}}}" style="text-align:center; {{{стиль_вверху3|}}}">{{{вверху3}}}</td></tr>}}<!-- Изображение -->{{#if:{{{изображение|}}}|<tr><td colspan="2" class="infobox-image {{{класс_изображения|}}}" style="{{{стиль_изображения|}}}"> {{{изображение}}} {{#if:{{{подпись|}}}| <div class="media-caption" style="{{{стиль_подписи|}}}">{{{подпись}}}</div>}}</td></tr>}}<!-- Изображение2 -->{{#if:{{{изображение2|}}}|<tr><td colspan="2" class="infobox-image {{{класс_изображения2|}}}" style="{{{стиль_изображения2|}}}"> {{{изображение2}}} {{#if:{{{подпись2|}}}| <div class="media-caption" style="{{{стиль_подписи2|}}}">{{{подпись2}}}</div>}}</td></tr>}}<!-- Изображение3 -->{{#if:{{{изображение3|}}}|<tr><td colspan="2" class="infobox-image {{{класс_изображения3|}}}" style="{{{стиль_изображения3|}}}"> {{{изображение3}}} {{#if:{{{подпись3|}}}| <div class="media-caption" style="{{{стиль_подписи3|}}}">{{{подпись3}}}</div>}}</td></tr>}}<!-- Строки -->{{#invoke:Infobox|renderLines}}<!-- Внизу -->{{Карточка/внизу| стиль_внизу_общий={{{стиль_внизу|}}}| класс_внизу={{{класс_внизу|}}}| внизу={{{внизу|}}}}}<!-- Внизу N -->{{#invoke:Transclude|npc|Карточка/внизу| стиль_внизу_общий={{{стиль_внизу|}}}| стиль_внизу=| класс_внизу=| внизу=}} </table><includeonly><!-- статьи -->{{#if:{{NAMESPACE}}||<!-- -->{{#if:{{{имя|}}}||[[Категория:Статьи с шаблонами-карточками без имени]]}}<!-- -->{{#ifeq:{{{имя|}}}|{{subst:PAGENAME}}|[[Категория:Статьи с шаблонами-карточками без имени]]}}<!-- -->}}<!-- шаблоны -->{{#ifeq:{{NAMESPACENUMBER}}|10|<!-- -->{{#if:{{{имя|}}}||[[Категория:Шаблоны-карточки без имени]]}}<!-- -->{{#ifeq:{{{имя|}}}|{{subst:PAGENAME}}|[[Категория:Шаблоны-карточки без имени]]}}<!-- -->{{#if:{{{название|}}}{{{стиль_названия|}}}|[[Категория:Шаблоны с использованием параметра «название» в шаблоне «Карточка»]]}}<!-- -->{{#if:{{{подпись|}}}{{{стиль_подписи|}}}{{{подпись2|}}}{{{стиль_подписи2|}}}{{{подпись3|}}}{{{стиль_подписи3|}}}|[[Категория:Шаблоны с использованием параметра «подпись» в шаблоне «Карточка»]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_тела|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_названия|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_вверху|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_вверху2|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_вверху3|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_подписи|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_подписи2|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_подписи3|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_заголовков|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_меток|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_текста|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_внизу|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifeq:{{{имя|}}}|{{PAGENAME}}|<!-- -->[[Категория:Шаблоны-карточки по алфавиту|{{ucfirst:{{без начала|{{PAGENAME}}|Карточка }}}}]]<!-- -->{{#if:{{{стиль_тела|}}}{{{стиль_вверху|}}}{{{стиль_заголовков|}}}{{{стиль_внизу|}}}|[[Категория:Википедия:Шаблоны-карточки с явным указанием стилей]]}}<!-- -->}}<!-- -->}}<!-- любое пространство имён -->{{#if:{{{название|}}}{{{стиль_названия|}}}|[[Категория:Википедия:Страницы с использованием параметра «название» в шаблоне «Карточка»]]}}<!-- -->{{#if:{{{подпись|}}}{{{стиль_подписи|}}}{{{подпись2|}}}{{{стиль_подписи2|}}}{{{подпись3|}}}{{{стиль_подписи3|}}}|[[Категория:Википедия:Страницы с использованием параметра «подпись» в шаблоне «Карточка»]]}}</includeonly><noinclude>{{doc}}</noinclude> 5bd0cadc0cad51dc109de7db63622ab36743d386 Шаблон:Карточка/Викисклад 10 135 312 2022-04-30T14:39:04Z ruwiki>ShinePhantom 0 еще одна проверочная категория для зачистки wikitext text/x-wiki {{wikidata|p373|{{str rep|{{str rep|{{{1|}}}|Category:|}}|category:|}}|plain=false|text=Медиафайлы на Викискладе|icon={{{icon|}}}|icon_size={{{icon_size|}}}|from={{{from|}}}}}<!-- -->{{#if: {{{nocat|}}}{{NAMESPACE}} || <!-- -->{{#if: {{{1|}}} | [[Категория:Википедия:Ссылка на Викисклад непосредственно в статье]]<!-- -->{{#if: {{wikidata|p373|plain=true}} | {{#ifeq: {{str rep|{{str rep|{{{1|}}}|Category:|}}|category:|}} | {{wikidata|p373|plain=true}} |[[Категория:Википедия:Ссылки на Викисклад в статье и на Викиданных совпадают]]| [[Категория:Википедия:Ссылки на Викисклад в статье и на Викиданных отличаются]] }} | [[Категория:Википедия:Ссылка на Викисклад в статье, но не на Викиданных]] }} }}<!-- --> }}<!-- -->{{#ifeq: {{NAMESPACE}} | Шаблон | {{#if: {{{2|}}} | [[Категория:Википедия:Шаблоны для низа карточек с лишним параметром]] }} }}<!-- --><noinclude> {{doc}} </noinclude> 40ef9a463c772ddbf54feae9e21d4037b692253e Шаблон:Карточка/импортёр 10 253 666 2022-05-06T07:31:20Z 176.122.109.173 0 оформление wikitext text/x-wiki <includeonly>{{ {{{|safesubst:}}}require subst | <noinclude></noinclude>{{Карточка {{subst:!}}{{subst:#if:{{{name|}}} |имя = {{{name}}} {{subst:!}}}}{{subst:#if:{{{bodyclass|}}} |класс_тела = {{{bodyclass}}} {{subst:!}}}}{{subst:#if:{{{bodystyle|}}} |стиль_тела = {{{bodystyle}}} {{subst:!}}}}{{subst:#if:{{{title|}}} |вверху = {{{title}}} {{subst:!}}}}{{subst:#if:{{{titleclass|}}} |класс_вверху = {{{titleclass}}} {{subst:!}}}}{{subst:#if:{{{titlestyle|}}} |стиль_вверху = {{{titlestyle}}} {{subst:!}}}}{{subst:#if:{{{above|}}} |вверху2 = {{{above}}} {{subst:!}}}}{{subst:#if:{{{aboveclass|}}} |класс_вверху2 = {{{aboveclass}}} {{subst:!}}}}{{subst:#if:{{{abovestyle|}}} |стиль_вверху2 = {{{abovestyle}}} {{subst:!}}}}{{subst:#if:{{{image|}}} |изображение = {{{image}}} {{subst:!}}}}{{subst:#if:{{{imageclass|}}} |класс_изображения = {{{imageclass}}} {{subst:!}}}}{{subst:#if:{{{imagestyle|}}} |стиль_изображения = {{{imagestyle}}} {{subst:!}}}}{{subst:#if:{{{caption|}}} |подпись = {{{caption}}} {{subst:!}}}}{{subst:#if:{{{captionstyle|}}} |стиль_подписи = {{{captionstyle}}} {{subst:!}}}}{{subst:#if:{{{headerstyle|}}} |стиль_заголовков = {{{headerstyle}}} {{subst:!}}}}{{subst:#if:{{{labelstyle|}}} |стиль_меток = {{{labelstyle}}} {{subst:!}}}}{{subst:#if:{{{datastyle|}}} |стиль_текста = {{{datastyle}}} {{subst:!}}}}{{subst:#if:{{{header1|}}} |заголовок1 = {{{header1}}} {{subst:!}}}}{{subst:#if:{{{label1|}}} |метка1 = {{{label1}}} {{subst:!}}}}{{subst:#if:{{{data1|}}} |текст1 = {{{data1}}} {{subst:!}}}}{{subst:#if:{{{class1|}}} |класс1 = {{{class1}}} {{subst:!}}}}{{subst:#if:{{{header2|}}} |заголовок2 = {{{header2}}} {{subst:!}}}}{{subst:#if:{{{label2|}}} |метка2 = {{{label2}}} {{subst:!}}}}{{subst:#if:{{{data2|}}} |текст2 = {{{data2}}} {{subst:!}}}}{{subst:#if:{{{class2|}}} |класс2 = {{{class2}}} {{subst:!}}}}{{subst:#if:{{{header3|}}} |заголовок3 = {{{header3}}} {{subst:!}}}}{{subst:#if:{{{label3|}}} |метка3 = {{{label3}}} {{subst:!}}}}{{subst:#if:{{{data3|}}} |текст3 = {{{data3}}} {{subst:!}}}}{{subst:#if:{{{class3|}}} |класс3 = {{{class3}}} {{subst:!}}}}{{subst:#if:{{{header4|}}} |заголовок4 = {{{header4}}} {{subst:!}}}}{{subst:#if:{{{label4|}}} |метка4 = {{{label4}}} {{subst:!}}}}{{subst:#if:{{{data4|}}} |текст4 = {{{data4}}} {{subst:!}}}}{{subst:#if:{{{class4|}}} |класс4 = {{{class4}}} {{subst:!}}}}{{subst:#if:{{{header5|}}} |заголовок5 = {{{header5}}} {{subst:!}}}}{{subst:#if:{{{label5|}}} |метка5 = {{{label5}}} {{subst:!}}}}{{subst:#if:{{{data5|}}} |текст5 = {{{data5}}} {{subst:!}}}}{{subst:#if:{{{class5|}}} |класс5 = {{{class5}}} {{subst:!}}}}{{subst:#if:{{{header6|}}} |заголовок6 = {{{header6}}} {{subst:!}}}}{{subst:#if:{{{label6|}}} |метка6 = {{{label6}}} {{subst:!}}}}{{subst:#if:{{{data6|}}} |текст6 = {{{data6}}} {{subst:!}}}}{{subst:#if:{{{class6|}}} |класс6 = {{{class6}}} {{subst:!}}}}{{subst:#if:{{{header7|}}} |заголовок7 = {{{header7}}} {{subst:!}}}}{{subst:#if:{{{label7|}}} |метка7 = {{{label7}}} {{subst:!}}}}{{subst:#if:{{{data7|}}} |текст7 = {{{data7}}} {{subst:!}}}}{{subst:#if:{{{class7|}}} |класс7 = {{{class7}}} {{subst:!}}}}{{subst:#if:{{{header8|}}} |заголовок8 = {{{header8}}} {{subst:!}}}}{{subst:#if:{{{label8|}}} |метка8 = {{{label8}}} {{subst:!}}}}{{subst:#if:{{{data8|}}} |текст8 = {{{data8}}} {{subst:!}}}}{{subst:#if:{{{class8|}}} |класс8 = {{{class8}}} {{subst:!}}}}{{subst:#if:{{{header9|}}} |заголовок9 = {{{header9}}} {{subst:!}}}}{{subst:#if:{{{label9|}}} |метка9 = {{{label9}}} {{subst:!}}}}{{subst:#if:{{{data9|}}} |текст9 = {{{data9}}} {{subst:!}}}}{{subst:#if:{{{class9|}}} |класс9 = {{{class9}}} {{subst:!}}}}{{subst:#if:{{{header10|}}} |заголовок10 = {{{header10}}} {{subst:!}}}}{{subst:#if:{{{label10|}}} |метка10 = {{{label10}}} {{subst:!}}}}{{subst:#if:{{{data10|}}} |текст10 = {{{data10}}} {{subst:!}}}}{{subst:#if:{{{class10|}}} |класс10 = {{{class10}}} {{subst:!}}}}{{subst:#if:{{{header11|}}} |заголовок11 = {{{header11}}} {{subst:!}}}}{{subst:#if:{{{label11|}}} |метка11 = {{{label11}}} {{subst:!}}}}{{subst:#if:{{{data11|}}} |текст11 = {{{data11}}} {{subst:!}}}}{{subst:#if:{{{class11|}}} |класс11 = {{{class11}}} {{subst:!}}}}{{subst:#if:{{{header12|}}} |заголовок12 = {{{header12}}} {{subst:!}}}}{{subst:#if:{{{label12|}}} |метка12 = {{{label12}}} {{subst:!}}}}{{subst:#if:{{{data12|}}} |текст12 = {{{data12}}} {{subst:!}}}}{{subst:#if:{{{class12|}}} |класс12 = {{{class12}}} {{subst:!}}}}{{subst:#if:{{{header13|}}} |заголовок13 = {{{header13}}} {{subst:!}}}}{{subst:#if:{{{label13|}}} |метка13 = {{{label13}}} {{subst:!}}}}{{subst:#if:{{{data13|}}} |текст13 = {{{data13}}} {{subst:!}}}}{{subst:#if:{{{class13|}}} |класс13 = {{{class13}}} {{subst:!}}}}{{subst:#if:{{{header14|}}} |заголовок14 = {{{header14}}} {{subst:!}}}}{{subst:#if:{{{label14|}}} |метка14 = {{{label14}}} {{subst:!}}}}{{subst:#if:{{{data14|}}} |текст14 = {{{data14}}} {{subst:!}}}}{{subst:#if:{{{class14|}}} |класс14 = {{{class14}}} {{subst:!}}}}{{subst:#if:{{{header15|}}} |заголовок15 = {{{header15}}} {{subst:!}}}}{{subst:#if:{{{label15|}}} |метка15 = {{{label15}}} {{subst:!}}}}{{subst:#if:{{{data15|}}} |текст15 = {{{data15}}} {{subst:!}}}}{{subst:#if:{{{class15|}}} |класс15 = {{{class15}}} {{subst:!}}}}{{subst:#if:{{{header16|}}} |заголовок16 = {{{header16}}} {{subst:!}}}}{{subst:#if:{{{label16|}}} |метка16 = {{{label16}}} {{subst:!}}}}{{subst:#if:{{{data16|}}} |текст16 = {{{data16}}} {{subst:!}}}}{{subst:#if:{{{class16|}}} |класс16 = {{{class16}}} {{subst:!}}}}{{subst:#if:{{{header17|}}} |заголовок17 = {{{header17}}} {{subst:!}}}}{{subst:#if:{{{label17|}}} |метка17 = {{{label17}}} {{subst:!}}}}{{subst:#if:{{{data17|}}} |текст17 = {{{data17}}} {{subst:!}}}}{{subst:#if:{{{class17|}}} |класс17 = {{{class17}}} {{subst:!}}}}{{subst:#if:{{{header18|}}} |заголовок18 = {{{header18}}} {{subst:!}}}}{{subst:#if:{{{label18|}}} |метка18 = {{{label18}}} {{subst:!}}}}{{subst:#if:{{{data18|}}} |текст18 = {{{data18}}} {{subst:!}}}}{{subst:#if:{{{class18|}}} |класс18 = {{{class18}}} {{subst:!}}}}{{subst:#if:{{{header19|}}} |заголовок19 = {{{header19}}} {{subst:!}}}}{{subst:#if:{{{label19|}}} |метка19 = {{{label19}}} {{subst:!}}}}{{subst:#if:{{{data19|}}} |текст19 = {{{data19}}} {{subst:!}}}}{{subst:#if:{{{class19|}}} |класс19 = {{{class19}}} {{subst:!}}}}{{subst:#if:{{{header20|}}} |заголовок20 = {{{header20}}} {{subst:!}}}}{{subst:#if:{{{label20|}}} |метка20 = {{{label20}}} {{subst:!}}}}{{subst:#if:{{{data20|}}} |текст20 = {{{data20}}} {{subst:!}}}}{{subst:#if:{{{class20|}}} |класс20 = {{{class20}}} {{subst:!}}}}{{subst:#if:{{{header21|}}} |заголовок21 = {{{header21}}} {{subst:!}}}}{{subst:#if:{{{label21|}}} |метка21 = {{{label21}}} {{subst:!}}}}{{subst:#if:{{{data21|}}} |текст21 = {{{data21}}} {{subst:!}}}}{{subst:#if:{{{class21|}}} |класс21 = {{{class21}}} {{subst:!}}}}{{subst:#if:{{{header22|}}} |заголовок22 = {{{header22}}} {{subst:!}}}}{{subst:#if:{{{label22|}}} |метка22 = {{{label22}}} {{subst:!}}}}{{subst:#if:{{{data22|}}} |текст22 = {{{data22}}} {{subst:!}}}}{{subst:#if:{{{class22|}}} |класс22 = {{{class22}}} {{subst:!}}}}{{subst:#if:{{{header23|}}} |заголовок23 = {{{header23}}} {{subst:!}}}}{{subst:#if:{{{label23|}}} |метка23 = {{{label23}}} {{subst:!}}}}{{subst:#if:{{{data23|}}} |текст23 = {{{data23}}} {{subst:!}}}}{{subst:#if:{{{class23|}}} |класс23 = {{{class23}}} {{subst:!}}}}{{subst:#if:{{{header24|}}} |заголовок24 = {{{header24}}} {{subst:!}}}}{{subst:#if:{{{label24|}}} |метка24 = {{{label24}}} {{subst:!}}}}{{subst:#if:{{{data24|}}} |текст24 = {{{data24}}} {{subst:!}}}}{{subst:#if:{{{class24|}}} |класс24 = {{{class24}}} {{subst:!}}}}{{subst:#if:{{{header25|}}} |заголовок25 = {{{header25}}} {{subst:!}}}}{{subst:#if:{{{label25|}}} |метка25 = {{{label25}}} {{subst:!}}}}{{subst:#if:{{{data25|}}} |текст25 = {{{data25}}} {{subst:!}}}}{{subst:#if:{{{class25|}}} |класс25 = {{{class25}}} {{subst:!}}}}{{subst:#if:{{{header26|}}} |заголовок26 = {{{header26}}} {{subst:!}}}}{{subst:#if:{{{label26|}}} |метка26 = {{{label26}}} {{subst:!}}}}{{subst:#if:{{{data26|}}} |текст26 = {{{data26}}} {{subst:!}}}}{{subst:#if:{{{class26|}}} |класс26 = {{{class26}}} {{subst:!}}}}{{subst:#if:{{{header27|}}} |заголовок27 = {{{header27}}} {{subst:!}}}}{{subst:#if:{{{label27|}}} |метка27 = {{{label27}}} {{subst:!}}}}{{subst:#if:{{{data27|}}} |текст27 = {{{data27}}} {{subst:!}}}}{{subst:#if:{{{class27|}}} |класс27 = {{{class27}}} {{subst:!}}}}{{subst:#if:{{{header28|}}} |заголовок28 = {{{header28}}} {{subst:!}}}}{{subst:#if:{{{label28|}}} |метка28 = {{{label28}}} {{subst:!}}}}{{subst:#if:{{{data28|}}} |текст28 = {{{data28}}} {{subst:!}}}}{{subst:#if:{{{class28|}}} |класс28 = {{{class28}}} {{subst:!}}}}{{subst:#if:{{{header29|}}} |заголовок29 = {{{header29}}} {{subst:!}}}}{{subst:#if:{{{label29|}}} |метка29 = {{{label29}}} {{subst:!}}}}{{subst:#if:{{{data29|}}} |текст29 = {{{data29}}} {{subst:!}}}}{{subst:#if:{{{class29|}}} |класс29 = {{{class29}}} {{subst:!}}}}{{subst:#if:{{{header30|}}} |заголовок30 = {{{header30}}} {{subst:!}}}}{{subst:#if:{{{label30|}}} |метка30 = {{{label30}}} {{subst:!}}}}{{subst:#if:{{{data30|}}} |текст30 = {{{data30}}} {{subst:!}}}}{{subst:#if:{{{class30|}}} |класс30 = {{{class30}}} {{subst:!}}}}{{subst:#if:{{{header31|}}} |заголовок31 = {{{header31}}} {{subst:!}}}}{{subst:#if:{{{label31|}}} |метка31 = {{{label31}}} {{subst:!}}}}{{subst:#if:{{{data31|}}} |текст31 = {{{data31}}} {{subst:!}}}}{{subst:#if:{{{class31|}}} |класс31 = {{{class31}}} {{subst:!}}}}{{subst:#if:{{{header32|}}} |заголовок32 = {{{header32}}} {{subst:!}}}}{{subst:#if:{{{label32|}}} |метка32 = {{{label32}}} {{subst:!}}}}{{subst:#if:{{{data32|}}} |текст32 = {{{data32}}} {{subst:!}}}}{{subst:#if:{{{class32|}}} |класс32 = {{{class32}}} {{subst:!}}}}{{subst:#if:{{{header33|}}} |заголовок33 = {{{header33}}} {{subst:!}}}}{{subst:#if:{{{label33|}}} |метка33 = {{{label33}}} {{subst:!}}}}{{subst:#if:{{{data33|}}} |текст33 = {{{data33}}} {{subst:!}}}}{{subst:#if:{{{class33|}}} |класс33 = {{{class33}}} {{subst:!}}}}{{subst:#if:{{{header34|}}} |заголовок34 = {{{header34}}} {{subst:!}}}}{{subst:#if:{{{label34|}}} |метка34 = {{{label34}}} {{subst:!}}}}{{subst:#if:{{{data34|}}} |текст34 = {{{data34}}} {{subst:!}}}}{{subst:#if:{{{class34|}}} |класс34 = {{{class34}}} {{subst:!}}}}{{subst:#if:{{{header35|}}} |заголовок35 = {{{header35}}} {{subst:!}}}}{{subst:#if:{{{label35|}}} |метка35 = {{{label35}}} {{subst:!}}}}{{subst:#if:{{{data35|}}} |текст35 = {{{data35}}} {{subst:!}}}}{{subst:#if:{{{class35|}}} |класс35 = {{{class35}}} {{subst:!}}}}{{subst:#if:{{{header36|}}} |заголовок36 = {{{header36}}} {{subst:!}}}}{{subst:#if:{{{label36|}}} |метка36 = {{{label36}}} {{subst:!}}}}{{subst:#if:{{{data36|}}} |текст36 = {{{data36}}} {{subst:!}}}}{{subst:#if:{{{class36|}}} |класс36 = {{{class36}}} {{subst:!}}}}{{subst:#if:{{{header37|}}} |заголовок37 = {{{header37}}} {{subst:!}}}}{{subst:#if:{{{label37|}}} |метка37 = {{{label37}}} {{subst:!}}}}{{subst:#if:{{{data37|}}} |текст37 = {{{data37}}} {{subst:!}}}}{{subst:#if:{{{class37|}}} |класс37 = {{{class37}}} {{subst:!}}}}{{subst:#if:{{{header38|}}} |заголовок38 = {{{header38}}} {{subst:!}}}}{{subst:#if:{{{label38|}}} |метка38 = {{{label38}}} {{subst:!}}}}{{subst:#if:{{{data38|}}} |текст38 = {{{data38}}} {{subst:!}}}}{{subst:#if:{{{class38|}}} |класс38 = {{{class38}}} {{subst:!}}}}{{subst:#if:{{{header39|}}} |заголовок39 = {{{header39}}} {{subst:!}}}}{{subst:#if:{{{label39|}}} |метка39 = {{{label39}}} {{subst:!}}}}{{subst:#if:{{{data39|}}} |текст39 = {{{data39}}} {{subst:!}}}}{{subst:#if:{{{class39|}}} |класс39 = {{{class39}}} {{subst:!}}}}{{subst:#if:{{{header40|}}} |заголовок40 = {{{header40}}} {{subst:!}}}}{{subst:#if:{{{label40|}}} |метка40 = {{{label40}}} {{subst:!}}}}{{subst:#if:{{{data40|}}} |текст40 = {{{data40}}} {{subst:!}}}}{{subst:#if:{{{class40|}}} |класс40 = {{{class40}}} {{subst:!}}}}{{subst:#if:{{{header41|}}} |заголовок41 = {{{header41}}} {{subst:!}}}}{{subst:#if:{{{label41|}}} |метка41 = {{{label41}}} {{subst:!}}}}{{subst:#if:{{{data41|}}} |текст41 = {{{data41}}} {{subst:!}}}}{{subst:#if:{{{class41|}}} |класс41 = {{{class41}}} {{subst:!}}}}{{subst:#if:{{{header42|}}} |заголовок42 = {{{header42}}} {{subst:!}}}}{{subst:#if:{{{label42|}}} |метка42 = {{{label42}}} {{subst:!}}}}{{subst:#if:{{{data42|}}} |текст42 = {{{data42}}} {{subst:!}}}}{{subst:#if:{{{class42|}}} |класс42 = {{{class42}}} {{subst:!}}}}{{subst:#if:{{{header43|}}} |заголовок43 = {{{header43}}} {{subst:!}}}}{{subst:#if:{{{label43|}}} |метка43 = {{{label43}}} {{subst:!}}}}{{subst:#if:{{{data43|}}} |текст43 = {{{data43}}} {{subst:!}}}}{{subst:#if:{{{class43|}}} |класс43 = {{{class43}}} {{subst:!}}}}{{subst:#if:{{{header44|}}} |заголовок44 = {{{header44}}} {{subst:!}}}}{{subst:#if:{{{label44|}}} |метка44 = {{{label44}}} {{subst:!}}}}{{subst:#if:{{{data44|}}} |текст44 = {{{data44}}} {{subst:!}}}}{{subst:#if:{{{class44|}}} |класс44 = {{{class44}}} {{subst:!}}}}{{subst:#if:{{{header45|}}} |заголовок45 = {{{header45}}} {{subst:!}}}}{{subst:#if:{{{label45|}}} |метка45 = {{{label45}}} {{subst:!}}}}{{subst:#if:{{{data45|}}} |текст45 = {{{data45}}} {{subst:!}}}}{{subst:#if:{{{class45|}}} |класс45 = {{{class45}}} {{subst:!}}}}{{subst:#if:{{{header46|}}} |заголовок46 = {{{header46}}} {{subst:!}}}}{{subst:#if:{{{label46|}}} |метка46 = {{{label46}}} {{subst:!}}}}{{subst:#if:{{{data46|}}} |текст46 = {{{data46}}} {{subst:!}}}}{{subst:#if:{{{class46|}}} |класс46 = {{{class46}}} {{subst:!}}}}{{subst:#if:{{{header47|}}} |заголовок47 = {{{header47}}} {{subst:!}}}}{{subst:#if:{{{label47|}}} |метка47 = {{{label47}}} {{subst:!}}}}{{subst:#if:{{{data47|}}} |текст47 = {{{data47}}} {{subst:!}}}}{{subst:#if:{{{class47|}}} |класс47 = {{{class47}}} {{subst:!}}}}{{subst:#if:{{{header48|}}} |заголовок48 = {{{header48}}} {{subst:!}}}}{{subst:#if:{{{label48|}}} |метка48 = {{{label48}}} {{subst:!}}}}{{subst:#if:{{{data48|}}} |текст48 = {{{data48}}} {{subst:!}}}}{{subst:#if:{{{class48|}}} |класс48 = {{{class48}}} {{subst:!}}}}{{subst:#if:{{{header49|}}} |заголовок49 = {{{header49}}} {{subst:!}}}}{{subst:#if:{{{label49|}}} |метка49 = {{{label49}}} {{subst:!}}}}{{subst:#if:{{{data49|}}} |текст49 = {{{data49}}} {{subst:!}}}}{{subst:#if:{{{class49|}}} |класс49 = {{{class49}}} {{subst:!}}}}{{subst:#if:{{{header50|}}} |заголовок50 = {{{header50}}} {{subst:!}}}}{{subst:#if:{{{label50|}}} |метка50 = {{{label50}}} {{subst:!}}}}{{subst:#if:{{{data50|}}} |текст50 = {{{data50}}} {{subst:!}}}}{{subst:#if:{{{class50|}}} |класс50 = {{{class50}}} {{subst:!}}}}{{subst:#if:{{{header51|}}} |заголовок51 = {{{header51}}} {{subst:!}}}}{{subst:#if:{{{label51|}}} |метка51 = {{{label51}}} {{subst:!}}}}{{subst:#if:{{{data51|}}} |текст51 = {{{data51}}} {{subst:!}}}}{{subst:#if:{{{class51|}}} |класс51 = {{{class51}}} {{subst:!}}}}{{subst:#if:{{{header52|}}} |заголовок52 = {{{header52}}} {{subst:!}}}}{{subst:#if:{{{label52|}}} |метка52 = {{{label52}}} {{subst:!}}}}{{subst:#if:{{{data52|}}} |текст52 = {{{data52}}} {{subst:!}}}}{{subst:#if:{{{class52|}}} |класс52 = {{{class52}}} {{subst:!}}}}{{subst:#if:{{{header53|}}} |заголовок53 = {{{header53}}} {{subst:!}}}}{{subst:#if:{{{label53|}}} |метка53 = {{{label53}}} {{subst:!}}}}{{subst:#if:{{{data53|}}} |текст53 = {{{data53}}} {{subst:!}}}}{{subst:#if:{{{class53|}}} |класс53 = {{{class53}}} {{subst:!}}}}{{subst:#if:{{{header54|}}} |заголовок54 = {{{header54}}} {{subst:!}}}}{{subst:#if:{{{label54|}}} |метка54 = {{{label54}}} {{subst:!}}}}{{subst:#if:{{{data54|}}} |текст54 = {{{data54}}} {{subst:!}}}}{{subst:#if:{{{class54|}}} |класс54 = {{{class54}}} {{subst:!}}}}{{subst:#if:{{{header55|}}} |заголовок55 = {{{header55}}} {{subst:!}}}}{{subst:#if:{{{label55|}}} |метка55 = {{{label55}}} {{subst:!}}}}{{subst:#if:{{{data55|}}} |текст55 = {{{data55}}} {{subst:!}}}}{{subst:#if:{{{class55|}}} |класс55 = {{{class55}}} {{subst:!}}}}{{subst:#if:{{{header56|}}} |заголовок56 = {{{header56}}} {{subst:!}}}}{{subst:#if:{{{label56|}}} |метка56 = {{{label56}}} {{subst:!}}}}{{subst:#if:{{{data56|}}} |текст56 = {{{data56}}} {{subst:!}}}}{{subst:#if:{{{class56|}}} |класс56 = {{{class56}}} {{subst:!}}}}{{subst:#if:{{{header57|}}} |заголовок57 = {{{header57}}} {{subst:!}}}}{{subst:#if:{{{label57|}}} |метка57 = {{{label57}}} {{subst:!}}}}{{subst:#if:{{{data57|}}} |текст57 = {{{data57}}} {{subst:!}}}}{{subst:#if:{{{class57|}}} |класс57 = {{{class57}}} {{subst:!}}}}{{subst:#if:{{{header58|}}} |заголовок58 = {{{header58}}} {{subst:!}}}}{{subst:#if:{{{label58|}}} |метка58 = {{{label58}}} {{subst:!}}}}{{subst:#if:{{{data58|}}} |текст58 = {{{data58}}} {{subst:!}}}}{{subst:#if:{{{class58|}}} |класс58 = {{{class58}}} {{subst:!}}}}{{subst:#if:{{{header59|}}} |заголовок59 = {{{header59}}} {{subst:!}}}}{{subst:#if:{{{label59|}}} |метка59 = {{{label59}}} {{subst:!}}}}{{subst:#if:{{{data59|}}} |текст59 = {{{data59}}} {{subst:!}}}}{{subst:#if:{{{class59|}}} |класс59 = {{{class59}}} {{subst:!}}}}{{subst:#if:{{{header60|}}} |заголовок60 = {{{header60}}} {{subst:!}}}}{{subst:#if:{{{label60|}}} |метка60 = {{{label60}}} {{subst:!}}}}{{subst:#if:{{{data60|}}} |текст60 = {{{data60}}} {{subst:!}}}}{{subst:#if:{{{class60|}}} |класс60 = {{{class60}}} {{subst:!}}}}{{subst:#if:{{{header61|}}} |заголовок61 = {{{header61}}} {{subst:!}}}}{{subst:#if:{{{label61|}}} |метка61 = {{{label61}}} {{subst:!}}}}{{subst:#if:{{{data61|}}} |текст61 = {{{data61}}} {{subst:!}}}}{{subst:#if:{{{class61|}}} |класс61 = {{{class61}}} {{subst:!}}}}{{subst:#if:{{{header62|}}} |заголовок62 = {{{header62}}} {{subst:!}}}}{{subst:#if:{{{label62|}}} |метка62 = {{{label62}}} {{subst:!}}}}{{subst:#if:{{{data62|}}} |текст62 = {{{data62}}} {{subst:!}}}}{{subst:#if:{{{class62|}}} |класс62 = {{{class62}}} {{subst:!}}}}{{subst:#if:{{{header63|}}} |заголовок63 = {{{header63}}} {{subst:!}}}}{{subst:#if:{{{label63|}}} |метка63 = {{{label63}}} {{subst:!}}}}{{subst:#if:{{{data63|}}} |текст63 = {{{data63}}} {{subst:!}}}}{{subst:#if:{{{class63|}}} |класс63 = {{{class63}}} {{subst:!}}}}{{subst:#if:{{{header64|}}} |заголовок64 = {{{header64}}} {{subst:!}}}}{{subst:#if:{{{label64|}}} |метка64 = {{{label64}}} {{subst:!}}}}{{subst:#if:{{{data64|}}} |текст64 = {{{data64}}} {{subst:!}}}}{{subst:#if:{{{class64|}}} |класс64 = {{{class64}}} {{subst:!}}}}{{subst:#if:{{{header65|}}} |заголовок65 = {{{header65}}} {{subst:!}}}}{{subst:#if:{{{label65|}}} |метка65 = {{{label65}}} {{subst:!}}}}{{subst:#if:{{{data65|}}} |текст65 = {{{data65}}} {{subst:!}}}}{{subst:#if:{{{class65|}}} |класс65 = {{{class65}}} {{subst:!}}}}{{subst:#if:{{{header66|}}} |заголовок66 = {{{header66}}} {{subst:!}}}}{{subst:#if:{{{label66|}}} |метка66 = {{{label66}}} {{subst:!}}}}{{subst:#if:{{{data66|}}} |текст66 = {{{data66}}} {{subst:!}}}}{{subst:#if:{{{class66|}}} |класс66 = {{{class66}}} {{subst:!}}}}{{subst:#if:{{{header67|}}} |заголовок67 = {{{header67}}} {{subst:!}}}}{{subst:#if:{{{label67|}}} |метка67 = {{{label67}}} {{subst:!}}}}{{subst:#if:{{{data67|}}} |текст67 = {{{data67}}} {{subst:!}}}}{{subst:#if:{{{class67|}}} |класс67 = {{{class67}}} {{subst:!}}}}{{subst:#if:{{{header68|}}} |заголовок68 = {{{header68}}} {{subst:!}}}}{{subst:#if:{{{label68|}}} |метка68 = {{{label68}}} {{subst:!}}}}{{subst:#if:{{{data68|}}} |текст68 = {{{data68}}} {{subst:!}}}}{{subst:#if:{{{class68|}}} |класс68 = {{{class68}}} {{subst:!}}}}{{subst:#if:{{{header69|}}} |заголовок69 = {{{header69}}} {{subst:!}}}}{{subst:#if:{{{label69|}}} |метка69 = {{{label69}}} {{subst:!}}}}{{subst:#if:{{{data69|}}} |текст69 = {{{data69}}} {{subst:!}}}}{{subst:#if:{{{class69|}}} |класс69 = {{{class69}}} {{subst:!}}}}{{subst:#if:{{{header70|}}} |заголовок70 = {{{header70}}} {{subst:!}}}}{{subst:#if:{{{label70|}}} |метка70 = {{{label70}}} {{subst:!}}}}{{subst:#if:{{{data70|}}} |текст70 = {{{data70}}} {{subst:!}}}}{{subst:#if:{{{class70|}}} |класс70 = {{{class70}}} {{subst:!}}}}{{subst:#if:{{{header71|}}} |заголовок71 = {{{header71}}} {{subst:!}}}}{{subst:#if:{{{label71|}}} |метка71 = {{{label71}}} {{subst:!}}}}{{subst:#if:{{{data71|}}} |текст71 = {{{data71}}} {{subst:!}}}}{{subst:#if:{{{class71|}}} |класс71 = {{{class71}}} {{subst:!}}}}{{subst:#if:{{{header72|}}} |заголовок72 = {{{header72}}} {{subst:!}}}}{{subst:#if:{{{label72|}}} |метка72 = {{{label72}}} {{subst:!}}}}{{subst:#if:{{{data72|}}} |текст72 = {{{data72}}} {{subst:!}}}}{{subst:#if:{{{class72|}}} |класс72 = {{{class72}}} {{subst:!}}}}{{subst:#if:{{{header73|}}} |заголовок73 = {{{header73}}} {{subst:!}}}}{{subst:#if:{{{label73|}}} |метка73 = {{{label73}}} {{subst:!}}}}{{subst:#if:{{{data73|}}} |текст73 = {{{data73}}} {{subst:!}}}}{{subst:#if:{{{class73|}}} |класс73 = {{{class73}}} {{subst:!}}}}{{subst:#if:{{{header74|}}} |заголовок74 = {{{header74}}} {{subst:!}}}}{{subst:#if:{{{label74|}}} |метка74 = {{{label74}}} {{subst:!}}}}{{subst:#if:{{{data74|}}} |текст74 = {{{data74}}} {{subst:!}}}}{{subst:#if:{{{class74|}}} |класс74 = {{{class74}}} {{subst:!}}}}{{subst:#if:{{{header75|}}} |заголовок75 = {{{header75}}} {{subst:!}}}}{{subst:#if:{{{label75|}}} |метка75 = {{{label75}}} {{subst:!}}}}{{subst:#if:{{{data75|}}} |текст75 = {{{data75}}} {{subst:!}}}}{{subst:#if:{{{class75|}}} |класс75 = {{{class75}}} {{subst:!}}}}{{subst:#if:{{{header76|}}} |заголовок76 = {{{header76}}} {{subst:!}}}}{{subst:#if:{{{label76|}}} |метка76 = {{{label76}}} {{subst:!}}}}{{subst:#if:{{{data76|}}} |текст76 = {{{data76}}} {{subst:!}}}}{{subst:#if:{{{class76|}}} |класс76 = {{{class76}}} {{subst:!}}}}{{subst:#if:{{{header77|}}} |заголовок77 = {{{header77}}} {{subst:!}}}}{{subst:#if:{{{label77|}}} |метка77 = {{{label77}}} {{subst:!}}}}{{subst:#if:{{{data77|}}} |текст77 = {{{data77}}} {{subst:!}}}}{{subst:#if:{{{class77|}}} |класс77 = {{{class77}}} {{subst:!}}}}{{subst:#if:{{{header78|}}} |заголовок78 = {{{header78}}} {{subst:!}}}}{{subst:#if:{{{label78|}}} |метка78 = {{{label78}}} {{subst:!}}}}{{subst:#if:{{{data78|}}} |текст78 = {{{data78}}} {{subst:!}}}}{{subst:#if:{{{class78|}}} |класс78 = {{{class78}}} {{subst:!}}}}{{subst:#if:{{{header79|}}} |заголовок79 = {{{header79}}} {{subst:!}}}}{{subst:#if:{{{label79|}}} |метка79 = {{{label79}}} {{subst:!}}}}{{subst:#if:{{{data79|}}} |текст79 = {{{data79}}} {{subst:!}}}}{{subst:#if:{{{class79|}}} |класс79 = {{{class79}}} {{subst:!}}}}{{subst:#if:{{{header80|}}} |заголовок80 = {{{header80}}} {{subst:!}}}}{{subst:#if:{{{label80|}}} |метка80 = {{{label80}}} {{subst:!}}}}{{subst:#if:{{{data80|}}} |текст80 = {{{data80}}} {{subst:!}}}}{{subst:#if:{{{class80|}}} |класс80 = {{{class80}}} {{subst:!}}}}{{subst:#if:{{{below|}}} |внизу = {{{below}}} {{subst:!}}}}{{subst:#if:{{{belowstyle|}}}|стиль_внизу = {{{belowstyle}}} }} }}|template=Карточка/импортёр|are_params=1 }}</includeonly><noinclude>{{doc}}</noinclude> 29a99ea8472f8d4050034a77d3570f625e60bf07 Шаблон:Импортёр шаблона-карточки 10 257 674 2022-06-27T07:21:21Z ruwiki>Leokand 0 оформление wikitext text/x-wiki {{ombox | text = Это [[Википедия:Обёртки шаблонов-карточек#Импортёры|импортёр]], преобразовывающий включение шаблона {{t|{{{3|{{PAGENAME}}}}}|lang={{#if:{{{2|}}}|{{{2|}}}|en}}}} во включение шаблона {{t|{{{1}}}}}. Для его использования выполните [[Википедия:Механизм шаблонов#Подстановка|подстановку]]: скопируйте код включения шаблона {{t|{{{3|{{PAGENAME}}}}}|lang={{#if:{{{2|}}}|{{{2|}}}|en}}}} из статьи другого раздела в статью русской Википедии, замените название шаблона: {{(!}} width="80%" align="center" {{!}}- {{!}} width="45%" {{!}} <p<includeonly>r</includeonly>e>{{{{{3|{{PAGENAME}}}}} {{pipe}} ... = ... }}</p<includeonly>r</includeonly>e> {{!}} &nbsp;→&nbsp; {{!}} <p<includeonly>r</includeonly>e>{{subst:{{#if:{{{1|}}}|{{{1|}}}/импортёр|{{PAGENAME}}}} {{pipe}} ... = ... }}</p<includeonly>r</includeonly>e> {{!)}} и сохраните страницу. Пожалуйста, не забывайте после этого переводить значения параметров, если и где необходимо. }}<includeonly>{{no-doc|nocat={{{nocat|}}}|[[Категория:Импортёры шаблонов-карточек]]}}</includeonly><noinclude>{{doc}}</noinclude> a73640b844d55fb1ba86e8b0f62016e9e86e95a8 Шаблон:Заготовка раздела 10 201 448 2022-07-09T00:19:32Z ruwiki>Iniquity 0 перевод на новые параметры wikitext text/x-wiki {{ {{{|safesubst:}}}#invoke:Unsubst||дата=__DATE__|$format=Y-m-d|$B= <!--{{Заготовка раздела}} begin-->{{ambox | name = Заготовка раздела | subst = <includeonly>{{subst:substcheck}}</includeonly> | type = content |image = [[Файл:Wiki letter w.svg|25px|link=|alt=]] | issue = Этот раздел '''[[Википедия:Заготовка статьи|не завершён]]'''. | talk = {{{talk|{{{обс|}}}}}} | fix = Вы поможете проекту, [[Википедия:Правила и указания|исправив и дополнив]] его{{#if: {{{1|}}} | <nowiki /> следующей информацией: {{{1}}} }}.<br>{{{comment|{{{c|{{{комм|{{{ком|{{{комментарий|{{{к|{{{com|{{{comm|}}}}}}}}}}}}}}}}}}}}}}}} | date = {{{date|{{{дата|}}}}}} | all = Википедия:Статьи с незавершёнными разделами | all2 = Википедия:Статьи с шаблонами недостатков по алфавиту | nocat = {{{nocat|}}} }} }}<noinclude>{{doc}}</noinclude> 354fe71955c1f4efa21d425cae329d66f9b43ce6 Шаблон:Ok 10 202 450 2022-08-08T15:45:49Z ruwiki>Sunpriat 0 wikitext text/x-wiki [[File:Yes check.svg|15px|link=|alt=✔]]<noinclude> <!--alt нужен чтобы скрин-ридеры читали в атрибуте alt "✓" как "отметка" и чтобы без загрузки картинок показывалось "✓". Без рамки "|мини" и с отключающим "|link=" подпись преобразовывается сайтом в два атрибута у img (alt и title), поэтому нужно сделать alt отдельно от title "File" вместо "Файл" немного уменьшает размер включений шаблонов.--> {{doc}} </noinclude> 43161c9f08276343b6f3c9223a73c712bd7db413 Шаблон:Pipe 10 256 672 2022-08-17T10:56:05Z ruwiki>Q-bit array 0 Изменил настройки защиты для «[[Шаблон:Pipe]]»: критический шаблон или модуль ([Редактирование=администраторы и инженеры] (бессрочно) [Переименование=администраторы и инженеры] (бессрочно)) wikitext text/x-wiki &#124;<noinclude> {{doc}} </noinclude> 7161a16776c0ed421759a1aee1e8f465d7b8949a Шаблон:Карточка/флаг и герб 10 170 382 2022-09-30T21:14:25Z ruwiki>Stjn 0 + поддержка поля from wikitext text/x-wiki {{#if:{{if-wikidata|p41|{{{флаг|}}}|1|from={{{from|}}}}}{{if-wikidata|p94|{{{герб|}}}|1|from={{{from|}}}}}|<table role="presentation" style="background:inherit; border-collapse:collapse; width:100%; display:table; text-align:center;"> <tr> {{if-wikidata|p41|{{{флаг|}}}|<td style<nowiki>=</nowiki>"vertical-align: middle">{{wikidata|p41|{{{флаг|}}}|from={{{from|}}}|border=true|size={{#if:{{{флаг ширина|}}}|{{{флаг ширина|}}}|160x160px}}|alt={{#if:{{{флаг подпись|}}} | {{{флаг подпись}}} | Флаг }} }}</td>}} {{if-wikidata|p94|{{{герб|}}}|<td style<nowiki>=</nowiki>"vertical-align: middle">{{wikidata|p94|{{{герб|}}}|from={{{from|}}}|size={{#if:{{{герб ширина|}}}|{{{герб ширина|}}}|90x160px}}|alt={{#if:{{{герб подпись|}}} | {{{герб подпись}}} | Герб }} }}</td>}} </tr> {{#if:{{if-wikidata|p41|{{{флаг|}}}|1|from={{{from|}}}}}{{if-wikidata|p94|{{{герб|}}}|1|from={{{from|}}}}}|<tr> {{if-wikidata|p41|{{{флаг|}}}|<td>{{#if:{{{флаг подпись|}}} | {{{флаг подпись}}} | Флаг }}</td>}} {{if-wikidata|p94|{{{герб|}}}|<td>{{#if:{{{герб подпись|}}} | {{{герб подпись}}} | Герб }}</td>}} </tr>}}</table> }}<noinclude>{{doc}}</noinclude> 6d024d548f061491090c2a71067f26911973a9fd Шаблон:Fmbox 10 223 494 2023-04-09T19:52:03Z ruwiki>QBA-bot 0 Изменил настройки защиты для «[[Шаблон:Fmbox]]»: критический шаблон или модуль (добавление защиты от переименований) ([Редактирование=администраторы и инженеры] (бессрочно) [Переименование=администраторы и инженеры] (бессрочно)) wikitext text/x-wiki {{#invoke:Message box|fmbox}}<noinclude> {{documentation}} <!-- Add categories and interwikis to the /doc subpage, not here! --> </noinclude> dfb511d767bd2208627c0874ccf91faf6b8551cc Шаблон:Параметры шаблона 10 224 496 2023-04-25T12:50:20Z ruwiki>Oleg Yunakov 0 Защитил страницу [[Шаблон:Параметры шаблона]]: критический шаблон или модуль: используется на 12 991 странице ([Редактирование=администраторы и инженеры] (бессрочно) [Переименование=администраторы и инженеры] (бессрочно)) wikitext text/x-wiki <span title="Смотреть с помощью инструмента Templatetiger">[//dimastbkbot.toolforge.org/template_params/?template={{urlencode:{{{1|{{PAGENAME}}}}}}}&lang=ruwiki использование шаблона]</span><!-- &nbsp;&bull; <span title="Смотреть с помощью инструмента Templatetiger">[//tools.wmflabs.org/templatetiger/template-parameter.php?template={{urlencode:{{{1|{{PAGENAME}}}}}}}&lang=ruwiki параметры]--> <small>[[Шаблон:Параметры шаблона|[?]]]</small><!--</span>--><noinclude>{{doc}}</noinclude> dcd4178efbe8f098263608dce37fd93b55b863c4 Модуль:Sidebar 828 81 134 2023-04-27T11:08:04Z ruwiki>Stjn 0 устаревший модуль, см. [[mw:Extension:Scribunto/Lua_reference_manual#strict]] Scribunto text/plain -- -- Этот модуль обеспечивает работу шаблона {{Sidebar}} -- require('strict') local p = {} local getArgs = require('Модуль:Arguments').getArgs local navbar = require('Модуль:Navbar')._navbar local function trimAndAddAutomaticNewline(s) -- For compatibility with the original {{sidebar with collapsible lists}} -- implementation, which passed some parameters through {{#if}} to trim -- their whitespace. This also triggered the automatic newline behavior. -- ([[meta:Help:Newlines and spaces#Automatic newline]]) s = mw.ustring.gsub(s, "^%s*(.-)%s*$", "%1") if mw.ustring.find(s, '^[#*:;]') or mw.ustring.find(s, '^{|') then return '\n' .. s else return s end end function p.sidebar(frame, args) if not args then args = getArgs(frame) end local root = mw.html.create() local child = args.child and mw.text.trim(args.child) == 'yes' if not child then root = root :tag('table') :addClass('vertical-navbox') :addClass(args.wraplinks ~= 'true' and 'nowraplinks' or nil) :addClass(args.bodyclass or args.class) :css('float', args.float or 'right') :css('clear', (args.float == 'none' and 'both') or args.float or 'right') :css('width', args.width or '22.0em') :css('margin', args.float == 'left' and '0 1.0em 1.0em 0' or '0 0 1.0em 1.0em') :css('background', '#f9f9f9') :css('border', '1px solid #aaa') :css('padding', '0.2em') :css('border-spacing', '0.4em 0') :css('text-align', 'center') :css('line-height', '1.4em') :css('font-size', '88%') :cssText(args.bodystyle or args.style) if args.outertitle then root :tag('caption') :addClass(args.outertitleclass) :css('padding-bottom', '0.2em') :css('font-size', '125%') :css('line-height', '1.2em') :css('font-weight', 'bold') :cssText(args.outertitlestyle) :wikitext(args.outertitle) end if args.topimage then local imageCell = root:tag('tr'):tag('td') imageCell :addClass(args.topimageclass) :css('padding', '0.4em 0') :cssText(args.topimagestyle) :wikitext(args.topimage) if args.topcaption then imageCell :tag('div') :css('padding-top', '0.2em') :css('line-height', '1.2em') :cssText(args.topcaptionstyle) :wikitext(args.topcaption) end end if args.pretitle then root :tag('tr') :tag('td') :addClass(args.pretitleclass) :cssText(args.basestyle) :css('padding-top', args.topimage and '0.2em' or '0.4em') :css('line-height', '1.2em') :cssText(args.pretitlestyle) :wikitext(args.pretitle) end end if args.title then if child then root :wikitext(args.title) :wikitext('</th></tr>') -- @todo replace this with unclosed again once mw.html gets it else root :tag('tr') :tag('th') :addClass(args.titleclass) :cssText(args.basestyle) :css('padding', '0.2em 0.4em 0.2em') :css('padding-top', args.pretitle and 0) :css('font-size', '145%') :css('line-height', '1.2em') :cssText(args.titlestyle) :wikitext(args.title) end end if args.image then local imageCell = root:tag('tr'):tag('td') imageCell :addClass(args.imageclass) :css('padding', '0.2em 0 0.4em') :cssText(args.imagestyle) :wikitext(args.image) if args.caption then imageCell :tag('div') :css('padding-top', '0.2em') :css('line-height', '1.2em') :cssText(args.captionstyle) :wikitext(args.caption) end end if args.above then root :tag('tr') :tag('td') :addClass(args.aboveclass) :css('padding', '0.3em 0.4em 0.3em') :css('font-weight', 'bold') :cssText(args.abovestyle) :newline() -- newline required for bullet-points to work :wikitext(args.above) end local rowNums = {} for k, v in pairs(args) do k = '' .. k local num = k:match('^heading(%d+)$') or k:match('^content(%d+)$') if num then table.insert(rowNums, tonumber(num)) end end table.sort(rowNums) -- remove duplicates from the list (e.g. 3 will be duplicated if both heading3 and content3 are specified) for i = #rowNums, 1, -1 do if rowNums[i] == rowNums[i - 1] then table.remove(rowNums, i) end end for i, num in ipairs(rowNums) do local heading = args['heading' .. num] if heading then root :tag('tr') :tag('th') :addClass(args.headingclass) :css('padding', '0.1em') :cssText(args.basestyle) :cssText(args.headingstyle) :cssText(args['heading' .. num .. 'style']) :newline() :wikitext(heading) end local content = args['content' .. num] if content then root :tag('tr') :tag('td') :addClass(args.contentclass) :css('padding', '0 0.1em 0.4em') :cssText(args.contentstyle) :cssText(args['content' .. num .. 'style']) :newline() :wikitext(content) :done() :newline() -- Without a linebreak after the </td>, a nested list like "* {{hlist| ...}}" doesn't parse correctly. end end if args.below then root :tag('tr') :tag('td') :addClass(args.belowclass) :css('padding', '0.3em 0.4em 0.3em') :css('font-weight', 'bold') :cssText(args.belowstyle) :newline() :wikitext(args.below) end if not child then local navbarArg = args.navbar or args.tnavbar if navbarArg ~= 'none' and navbarArg ~= 'off' and (args.name or frame:getParent():getTitle():gsub('/sandbox$', '') ~= 'Шаблон:Sidebar') then root :tag('tr') :tag('td') :css('text-align', 'right') :css('font-size', '115%') :cssText(args.navbarstyle or args.tnavbarstyle) :wikitext(navbar{ args.name, mini = 1, fontstyle = args.navbarfontstyle or args.tnavbarfontstyle }) end end return tostring(root) end function p.collapsible(frame) local args = getArgs(frame) args.abovestyle = 'border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;' .. (args.abovestyle or '') args.belowstyle = 'border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;' .. (args.belowstyle or '') args.navbarstyle = 'padding-top: 0.6em;' .. (args.navbarstyle or args.tnavbarstyle or '') if not args.name and frame:getParent():getTitle():gsub('/sandbox$', '') == 'Шаблон:Sidebar with collapsible lists' then args.navbar = 'none' end local contentArgs = {} for k, v in pairs(args) do local num = string.match(k, '^list(%d+)$') if num then local expand = args.expanded and (args.expanded == 'all' or args.expanded == args['list' .. num .. 'name']) local row = mw.html.create('div') row :addClass('NavFrame') :addClass((not expand) and 'collapsed' or nil) :css('border', 'none') :css('padding', 0) :cssText(args.listframestyle) :cssText(args['list' .. num .. 'framestyle']) :tag('div') :addClass('NavHead') :addClass(args.listtitleclass) :css('font-size', '105%') :css('background', 'transparent') :css('text-align', 'left') :cssText(args.basestyle) :cssText(args.listtitlestyle) :cssText(args['list' .. num .. 'titlestyle']) :wikitext(trimAndAddAutomaticNewline(args['list' .. num .. 'title'] or 'List')) :done() :tag('div') :addClass('NavContent') :addClass(args.listclass) :addClass(args['list' .. num .. 'class']) :css('font-size', '105%') :css('padding', '0.2em 0 0.4em') :css('text-align', 'center') :cssText(args.liststyle) :cssText(args['list' .. num .. 'style']) :wikitext(trimAndAddAutomaticNewline(args['list' .. num])) contentArgs['content' .. num] = tostring(row) end end for k, v in pairs(contentArgs) do args[k] = v end return p.sidebar(frame, args) end return p e8d033060367055f925583e3102d31899d0dce9d Шаблон:Para 10 218 484 2023-05-02T10:07:35Z ruwiki>Iniquity 0 занесем в проверку второй параметр wikitext text/x-wiki <code style="white-space:nowrap;">&#124;{{#if:{{{1|}}}|<span style="color:#767600;">{{{1}}}</span> &#61; {{{2|}}}|<span style="color:#767600;">{{{2|}}}</span>}}</code><noinclude> {{doc}} </noinclude> 2fd0e9f403fb5a42e97b773185e89bc43323bb37 Модуль:Wikidata/url 828 285 731 2023-05-09T00:51:03Z ruwiki>Putnik 0 оптимизация потребления памяти за счёт замены mw.wikibase.getEntity() на mw.wikibase.getBestStatements() Scribunto text/plain local p = {} local function formatLangRefs( options ) local langRefs = {} if options.qualifiers and options.qualifiers.P407 then for _, qualifier in ipairs( options.qualifiers.P407 ) do if ( qualifier and qualifier.datavalue and qualifier.datavalue.type == 'wikibase-entityid' ) then local qualifierId = qualifier.datavalue.value.id local wbStatus, langRefCodeClaims = pcall( mw.wikibase.getBestStatements, qualifierId, 'P218' ) if wbStatus and langRefCodeClaims then for _, claim in ipairs( langRefCodeClaims ) do if ( claim.mainsnak and claim.mainsnak.datavalue and claim.mainsnak.datavalue.type == 'string' ) then local langRefCode = claim.mainsnak.datavalue.value table.insert( langRefs, options.frame:expandTemplate{ title = 'ref-' .. langRefCode } ) end end end end end end return table.concat( langRefs, '&#8203;' ) end function p.formatUrlValue( context, options, value ) local moduleUrl = require( 'Module:URL' ) local langRefs = formatLangRefs( options ) if not options.length or options.length == '' then options.length = math.max( 18, 25 - #langRefs ) end return moduleUrl.formatUrlSingle( context, options, value ) .. langRefs end return p 4a9959f45666b35899729e561a73e0535c16e15e Модуль:WikidataSelectors 828 141 324 2023-05-09T18:46:16Z ruwiki>Putnik 0 исправление метода load() Scribunto text/plain local i18n = { ["errors"] = { ["rank-not-valid"] = "Некорретное значение приоритета (rank)", ["cant-parse-condition"] = "Не удалось разобрать условие" } } local validRanks = { 'best', 'preferred', 'normal', 'deprecated' } --[[ Internal function for error message Input: key in errors table Output: error message ]] local function throwError( key ) error( i18n.errors[key] ) end local p = {} --[[ Load property and filter statements Input: entityId, selector string Output: filtered statements table ]] function p.load( entityId, propertySelector ) local propertyId = mw.ustring.match( propertySelector, '^[Pp]%d+' ) if not propertyId then return nil end propertyId = string.upper( propertyId ) local allStatements = {} allStatements[ propertyId ] = mw.wikibase.getAllStatements( entityId, propertyId ) return p.filter( allStatements, propertySelector ) end --[[ Parse selectors and filter statements Input: statements table, selector string Output: filtered statements table ]] function p.filter( allClaims, propertySelector ) propertySelector = mw.text.trim( propertySelector ) -- Get property ID from selector local propertyId = mw.ustring.match( propertySelector, '^[Pp]%d+' ) if not propertyId then propertyId = '' end local initPos = #propertyId + 1 propertyId = string.upper( propertyId ) if ( not allClaims ) then return nil end local allPropertyClaims = allClaims[propertyId] if ( not allPropertyClaims ) then return nil end -- Gathering rules local rules = p.matchSelectors( propertySelector, initPos ) -- If there is no rank filter, than default rank is 'best' local isRanked = false for i, subRules in ipairs( rules ) do for j, rule in ipairs( subRules ) do if rule['type'] == 'rank' then isRanked = true break end end end if not isRanked then table.insert( rules, 1, { { type = 'rank', value = 'best' } } ) end -- Execute rules allPropertyClaims = p.applyRules( allPropertyClaims, rules ) return allPropertyClaims end --[[ Match and gather selector rules Input: string with selectors rules, start position Output: rules table ]] function p.matchSelectors( selectorsString, initPos ) local rules = {} local rawRulePattern = '^%s*%[%s*[^%[%]]+%s*%]%s*' local rulePattern = '^%s*%[%s*([^%[%]]+)%s*%]%s*$' if not initPos then initPos = 1 end local rawRule = mw.ustring.match( selectorsString, rawRulePattern, initPos ) while rawRule do initPos = initPos + #rawRule rule = mw.ustring.match( rawRule, rulePattern ) rule = mw.text.trim( rule ) local subRules = mw.text.split( rule, '%s*,%s*' ) local commands = {} local comm for i, subRule in ipairs( subRules ) do local isInversed = false if mw.ustring.match( subRule, '^!' ) then isInversed = true subRule = mw.ustring.match( subRule, '^!%s*(.+)$' ) end -- p123[1] if mw.ustring.match( subRule, '^%d+$' ) then table.insert( commands, { type = 'position', value = subRule, inversed = isInversed } ) -- p123[rank:preferred] elseif mw.ustring.match( subRule, '^rank%s*:%s*(%a+)$' ) then rank = mw.ustring.match( subRule, '^rank%s*:%s*(%a+)$' ) table.insert( commands, { type = 'rank', value = rank, inversed = isInversed } ) -- p123[language:xx] elseif mw.ustring.match( subRule, '^language%s*:%s*([%a%-]+)$' ) then value = mw.ustring.match( subRule, '^language%s*:%s*([%a%-]+)$' ) table.insert( commands, { type = 'language', value = value, inversed = isInversed } ) -- p123[language!:xx] elseif mw.ustring.match( subRule, '^language%s*!:%s*([%a%-]+)$' ) then value = mw.ustring.match( subRule, '^language%s*!:%s*([%a%-]+)$' ) table.insert( commands, { type = 'language', value = value, inversed = not isInversed } ) -- p123[min] elseif mw.ustring.match( subRule, '^min$' ) then table.insert( commands, { type = 'value_min' } ) -- p123[max] elseif mw.ustring.match( subRule, '^max$' ) then table.insert( commands, { type = 'value_max' } ) -- p123[min:p456] elseif mw.ustring.match( subRule, '^min%s*:%s*[Pp]%d+$' ) then value = mw.ustring.match( subRule, ':%s*([Pp]%d+)$' ) table.insert( commands, { type = 'qualifier_min', qualifier = value } ) -- p123[max:p456] elseif mw.ustring.match( subRule, '^max%s*:%s*[Pp]%d+$' ) then value = mw.ustring.match( subRule, ':%s*([Pp]%d+)$' ) table.insert( commands, { type = 'qualifier_max', qualifier = value } ) -- p123[unit:q789] elseif mw.ustring.match( subRule, '^unit%s*:%s*[^%[%],:]+$' ) then value = mw.ustring.match( subRule, ':%s*([^%[%],:]+)$' ) table.insert( commands, { type = 'unit', value = value, inversed = isInversed } ) -- p123[unit!:q789] elseif mw.ustring.match( subRule, '^unit%s*!:%s*[^%[%],:]+$' ) then value = mw.ustring.match( subRule, '!:%s*([^%[%],:]+)$' ) table.insert( commands, { type = 'unit', value = value, inversed = not isInversed } ) -- p123[p456] elseif mw.ustring.match( subRule, '^[Pp]%d+$' ) then qualifier = mw.ustring.match( subRule, '^[Pp]%d+' ) table.insert( commands, { type = 'qualifier', qualifier = qualifier, value = nil, inversed = isInversed } ) -- p123[p456:q789] elseif mw.ustring.match( subRule, '^[Pp]%d+%s*:%s*[^%[%],:]+$' ) then qualifier = mw.ustring.match( subRule, '^([Pp]%d+)%s*:?' ) value = mw.ustring.match( subRule, ':%s*([^%[%],:]+)$' ) table.insert( commands, { type = 'qualifier', qualifier = qualifier, value = value, inversed = isInversed } ) -- p123[p456!:q789] elseif mw.ustring.match( subRule, '^[Pp]%d+%s*!:%s*[^%[%],:]+$' ) then qualifier = mw.ustring.match( subRule, '^([Pp]%d+)%s*!:?' ) value = mw.ustring.match( subRule, '!:%s*([^%[%],:]+)$' ) table.insert( commands, { type = 'qualifier', qualifier = qualifier, value = value, inversed = not isInversed } ) -- p123[q456] elseif mw.ustring.match( subRule, '^[Qq]%d+$' ) then value = mw.ustring.match( subRule, '^[Qq]%d+' ) table.insert( commands, { type = 'value', value = value, inversed = isInversed } ) else throwError( 'cant-parse-condition' ) end end if #commands then table.insert( rules, commands ) end rawRule = mw.ustring.match( selectorsString, rawRulePattern, initPos ) end return rules end --[[ Intercept statements with selector rules Input: statements table, selector rules Output: filtered statements table ]] function p.applyRules( claims, rules ) for i, subRules in ipairs( rules ) do local newClaims = {} for j, rule in ipairs( subRules ) do if rule['type'] == 'rank' then table.insert( newClaims, p.filterByRank( claims, rule['value'], rule['inversed'] ) ) elseif rule['type'] == 'language' then table.insert( newClaims, p.filterByLanguage( claims, rule['value'], rule['inversed'] ) ) elseif rule['type'] == 'unit' then table.insert( newClaims, p.filterByUnit( claims, rule['value'], rule['inversed'] ) ) elseif rule['type'] == 'position' then table.insert( newClaims, p.filterByPosition( claims, rule['value'], rule['inversed'] ) ) elseif rule['type'] == 'qualifier' then table.insert( newClaims, p.filterByQualifier( claims, rule['qualifier'], rule['value'], rule['inversed'] ) ) elseif rule['type'] == 'qualifier_min' then table.insert( newClaims, p.filterUtterByQualifier( claims, rule['qualifier'], true ) ) elseif rule['type'] == 'qualifier_max' then table.insert( newClaims, p.filterUtterByQualifier( claims, rule['qualifier'], false ) ) elseif rule['type'] == 'value' then table.insert( newClaims, p.filterByValue( claims, rule['value'], rule['inversed'] ) ) elseif rule['type'] == 'value_min' then table.insert( newClaims, p.filterUtter( claims, true ) ) elseif rule['type'] == 'value_max' then table.insert( newClaims, p.filterUtter( claims, false ) ) end end claims = {} --[[ Merge all claims TODO: It's not good ]] for j, newSubClaims in ipairs( newClaims ) do for k, newClaim in ipairs( newSubClaims ) do local isNew = true for l, oldClaim in ipairs( claims ) do if oldClaim['id'] == newClaim['id'] then isNew = false break end end if isNew then table.insert( claims, newClaim ) end end end end return claims end --[[ Filter statements by rank Input: claims table, rank value, inversion Output: filtered statements table ]] function p.filterByRank( claims, rank, inversed ) if not inversed then inversed = false end if not rank then rank = 'best' end -- Check if rank value is valid local isValidRank = false for i, validRank in ipairs( validRanks ) do if rank == validRank then isValidRank = true break end end if not isValidRank then throwError( 'rank-not-valid' ) end -- Find the best rank if rank == 'best' then rank = 'normal' -- default rank (don't use deprecated even if it's no more claims) -- If we have at least one preferred rank, mark it as best for i, statement in pairs( claims ) do if (statement.rank == 'preferred') then rank = 'preferred' break end end end local resultClaims = {}; for i, statement in pairs( claims ) do if ( statement.rank == rank ) ~= inversed then table.insert( resultClaims, statement ) end end return resultClaims end --[[ Filter statements by language of value Input: claims table, language, inversion Output: filtered statements table ]] function p.filterByLanguage( claims, language, inversed ) if not inversed then inversed = false end local resultClaims = {} local mulStatement = {} for i, statement in ipairs( claims ) do isMatchLanguage = false if statement['mainsnak'] and statement['mainsnak']['datavalue'] and statement['mainsnak']['datavalue']['value'] and statement['mainsnak']['datavalue']['value']['language'] then if statement['mainsnak']['datavalue']['value']['language'] == language then isMatchLanguage = true end if statement['mainsnak']['datavalue']['value']['language'] == 'mul' then mulStatement = statement end end if isMatchLanguage ~= inversed then table.insert( resultClaims, statement ) end end if next(resultClaims) == nil and next(mulStatement) ~= nil then -- if specific language is not found, but there is Q20923490 value table.insert( resultClaims, mulStatement ) end return resultClaims end --[[ Filter statements by unit of value Input: claims table, unit, inversion Output: filtered statements table ]] function p.filterByUnit( claims, unit, inversed ) if not inversed then inversed = false end unit = 'http://www.wikidata.org/entity/' .. string.upper( unit ) local resultClaims = {} for i, statement in ipairs( claims ) do isMatchUnit = false if statement['mainsnak'] and statement['mainsnak']['datavalue'] and statement['mainsnak']['datavalue']['value'] and statement['mainsnak']['datavalue']['value']['unit'] and statement['mainsnak']['datavalue']['value']['unit'] == unit then isMatchUnit = true end if isMatchUnit ~= inversed then table.insert( resultClaims, statement ) break end end return resultClaims end --[[ Filter statements by position Input: claims table, position, inversion Output: filtered statements table ]] function p.filterByPosition( claims, position, inversed ) if not inversed then inversed = false end local resultClaims = {}; for statementPosition, statement in ipairs( claims ) do if ( statementPosition == tonumber( position ) ) ~= inversed then table.insert( resultClaims, statement ) break end end return resultClaims end --[[ Filter statements by qualifier existance or it's value Input: claims table, ID of qualifier's property, qualifier's value, inversion Output: filtered statements table ]] function p.filterByQualifier( claims, qualifierId, value, inversed ) if not inversed then inversed = false end qualifierId = string.upper( qualifierId ) local resultClaims = {} for i, statement in ipairs( claims ) do if statement['qualifiers'] and statement['qualifiers'][qualifierId] then if value == nil then if ( #statement['qualifiers'][qualifierId] > 0 ) ~= inversed then table.insert( resultClaims, statement ) end else local isQualifierFound = false for j, qualifier in ipairs( statement['qualifiers'][qualifierId] ) do if qualifier['datavalue'] then local qualifierValue = qualifier['datavalue']['value'] if qualifier['datavalue']['type'] == 'wikibase-entityid' then qualifierValue = qualifierValue.id value = string.upper( value ) end if qualifierValue == value then isQualifierFound = true break end end end if isQualifierFound ~= inversed then table.insert( resultClaims, statement ) end end elseif inversed then table.insert( resultClaims, statement ) end end return resultClaims end --[[ Filter statements by it's values Input: claims table, value, inversed Output: filtered statements table ]] function p.filterByValue( claims, value, inversed ) inversed = inversed or false local resultClaims = {} for i, statement in ipairs( claims ) do local statementValue if statement['mainsnak'] and statement['mainsnak']['datavalue'] and statement['mainsnak']['datavalue']['type'] then statementValue = statement['mainsnak']['datavalue']['value'] if statement['mainsnak']['datavalue']['type'] == 'quantity' then statementValue = statementValue.amount end if statement['mainsnak']['datavalue']['type'] == 'time' then statementValue = statementValue.time end if statement['mainsnak']['datavalue']['type'] == 'wikibase-entityid' then statementValue = statementValue.id value = string.upper( value ) end end if ( statementValue == value ) ~= inversed then table.insert( resultClaims, statement ) end end return resultClaims end --[[ Find a statement with minimum or maximum value Input: claims table, asc, inversed Output: filtered statements table ]] function p.filterUtter( claims, asc, inversed ) local resultValue = nil for i, statement in ipairs( claims ) do local statementValue if statement['mainsnak'] and statement['mainsnak']['datavalue'] and statement['mainsnak']['datavalue']['type'] then statementValue = statement['mainsnak']['datavalue']['value'] if statement['mainsnak']['datavalue']['type'] == 'quantity' then statementValue = statementValue.amount end if statement['mainsnak']['datavalue']['type'] == 'time' then statementValue = statementValue.time end if statement['mainsnak']['datavalue']['type'] == 'wikibase-entityid' then statementValue = statementValue.id end if not resultValue or ( statementValue < resultValue ) == asc then resultValue = statementValue end end end mw.logObject( resultValue, 'resultValue' ) return p.filterByValue( claims, resultValue, inversed ) end --[[ Find a statement with minimum or maximum qualifier value Input: claims table, qualifierId, asc Output: filtered statements table ]] function p.filterUtterByQualifier( claims, qualifierId, asc ) qualifierId = string.upper( qualifierId ) local resultValue = nil local resultStatement = nil for i, statement in ipairs( claims ) do if not statement['qualifiers'] and not statement['qualifiers'][qualifierId] then if resultStatement == nil then resultStatement = statement end else for _, qualifier in ipairs( statement['qualifiers'][qualifierId] ) do if qualifier['datavalue'] then local qualifierValue = qualifier['datavalue']['value'] if qualifier['datavalue']['type'] == 'quantity' then qualifierValue = qualifierValue.amount end if qualifier['datavalue']['type'] == 'time' then qualifierValue = qualifierValue.time end if qualifier['datavalue']['type'] == 'wikibase-entityid' then qualifierValue = qualifierValue.id end if not resultValue or ( qualifierValue < resultValue ) == asc then resultStatement = statement resultValue = qualifierValue end end end end end return { resultStatement } end return p 0bdff3a63bf171160cdec5c966211fbbf3003880 Модуль:Wikibase 828 92 156 2023-05-09T22:41:38Z ruwiki>Putnik 0 getEntityObject() → getEntity() Scribunto text/plain -- Модуль для функционала Викиданных local M = {}; local function tabletostr( t, fmt, s, o, c ) -- не для использования на страницах if type( t ) == "table" then local f = {}; for k, v in pairs( t ) do table.insert( f, string.format( fmt or '%s = %s', k, tabletostr( v, fmt, s, o, c ) ) ) end; table.sort( f ); return ( o or '' ) .. table.concat( f, s or '' ) .. ( c or '' ) else return tostring( t ) end end function M.wbview( ref, id ) -- вспом. функция для подписи из Викиданных local l = mw.wikibase.label( id ); return l and ( l == ref and l or ref .. '|' .. l .. ( mw.ustring.lower( l ) == mw.ustring.lower( ref ) and '' or '<sup>*</sup>' ) ) or ref end function M.id( frame ) -- Элемент текущей страницы в Викиданных --Если вызван с параметром, достаёт id значения данного свойства, иначе возвращает id страницы --Второй параметр - разделитель, если значений несколько ("; " по умолчанию), -- либо можно указать номер параметром n. Третий параметр - формат для строкового свойства, -- по умолчанию "%s" local function try() local e = mw.wikibase.getEntity(); if frame.args[ 1 ] then local function gv( i ) local z = e.claims[ frame.args[ 1 ] ][ i ].mainsnak.datavalue; if z.type == 'wikibase-entityid' then return z.value.id else return string.format( frame.args[ 3 ] or '%s', tabletostr( z.value, "%s", '; ', '{', '}' ) ) end end if frame.args[ 'n' ] then return gv( tonumber( frame.args[ 'n' ] ) ) end local p, h = e.claims[ frame.args[ 1 ] ], {} for n, v in pairs( p ) do h[ n ] = gv( n ) end return table.concat( h, frame.args[ 2 ] or "; " ) else return e.id end end local r, result = pcall( try ); if r then return result; else return '<strong class="error">В Викиданных нет записей для текущей страницы</strong>'; end end function M.struc( frame ) -- Отладочная функция, будет перенесена в отдельный модуль --Структуру см. [[mw:Extension:WikibaseClient/Lua#Entity table and data structure]] local function try() local i, e = 1, mw.wikibase.getEntity(); while frame.args[i] do e = e[ frame.args[ i ] ] or e[ tonumber( frame.args[ i ] ) ]; i = i + 1 end return tabletostr( e, frame.args[ 'f' ], frame.args[ 's' ] or '; ', '{', '}' ) end local r, result = pcall( try ); if r then return result; else return '<strong class="error">В Викиданных нет записей для текущей страницы</strong>'; end end function M.label( frame ) -- Комментарий к элементу Викиданных в 1-м параметре local function try() local id = frame.args[1]; if not id or id == '' then id = mw.wikibase.getEntityIdForCurrentPage(); -- error, если нет элемента end return mw.wikibase.label( id ); end local r, result = pcall( try ); if r then return result; else return '<strong class="error">В Викиданных нет записей для текущей страницы</strong>'; end end function M.description( frame ) local function try() local entityId = frame.args[1]; if not entityId or entityId == '' then entityId = mw.wikibase.getEntityIdForCurrentPage(); -- error, если нет элемента end return mw.wikibase.description( entityId ) end local r, result = pcall( try ); if r then return result; else return '<strong class="error">В Викиданных нет записей для указанной страницы</strong>'; end end function M.iwiki( frame ) -- Интервики для указанного языка (только с ВД) local function try() if frame.args[ 1 ] then return mw.wikibase.getEntity().sitelinks[ frame.args[ 1 ] .. 'wiki' ].title else-- список интервик local r = {}; for k, v in pairs( mw.wikibase.getEntity().sitelinks ) do table.insert( r, string.format( frame.args[ 'f' ] or "* [[:%s:%s]]\n", v.language, v.title ) ) end return table.concat( r ) end end local r, result = pcall( try ); if r then return result; else return '<strong class="error">В Викиданных нет записей для текущей страницы</strong>'; end end function M.iwikiall( frame ) -- Все ссылки, привязанные к элементу на ВД, в т.ч. викигид и склад local function try() if frame.args[ 1 ] then return mw.wikibase.getEntity().sitelinks[ frame.args[ 1 ] ].title else-- список интервик local r = {}; for k, v in pairs( mw.wikibase.getEntity().sitelinks ) do table.insert( r, string.format( frame.args[ 'f' ] or "* [[:%s:%s]]\n", v.language, v.title ) ) end return table.concat(r) end end local r, result = pcall( try ); if r then return result; else return ''; end end function M.page( frame ) -- страница Рувики для данного элемента local function try() return mw.wikibase.sitelink( frame.args[ 1 ] ) end local r, result = pcall( try ); if r then return result; else return '<strong class="error">В Викиданных нет записей для текущей страницы</strong>'; end end function M.wdprops( frame ) -- список всех свойств с ВД в человеко-читаемом виде local function try() local e, r = mw.wikibase.getEntity(), {}; for p, a in pairs( e.claims ) do local label = mw.wikibase.label( p ) or string.format( [[d:%s]], p ); local vals = {}; for n, v in pairs( a ) do local w = v.mainsnak.datavalue; vals[ n ] = ( w.type == 'wikibase-entityid' and '[[' .. M.wbview( mw.wikibase.sitelink( w.value.id ) or 'd:' .. w.value.id, w.value.id ) .. ']]' or M.tabletostr( w.value ) ) end table.insert( r, string.format( frame.args[ 'f' ] or '\n|-\n|rowspan=%i|%s\n|%s', #vals, label, table.concat( vals, frame.args[ 's' ] or '\n|-\n|' ) ) ) end--for return table.concat( r ) end local r, result = pcall( try ); if r then return result; else return '<strong class="error">В Викиданных нет записей для текущей страницы</strong>'; end end return M fc7c167bb9ef635b35a685123b273c486c229190 Модуль:Calendar 828 62 96 2023-05-17T17:44:45Z ruwiki>Dima st bk 0 + короткие варианты для английского, см. [[Обсуждение шаблона:Cite web#Формат параметра %7Carchive-date=]] Scribunto text/plain local p = {} -- Необходимые модули и переменные local getArgs = require('Module:Arguments').getArgs local yesno = require('Module:Yesno') local mwlang = mw.getContentLanguage() local err = "―" -- NthDay nil result local tCon = table.concat -- 00) Блок многократно используемых списков local bool_to_number={ [true]=1, [false]=0 } local monthlang = {"января","февраля","марта","апреля","мая","июня","июля","августа","сентября","октября","ноября","декабря"} local month_to_num = {["января"]=1,["февраля"]=2,["марта"]=3,["апреля"]=4,["мая"]=5,["июня"]=6, ["июля"]=7,["августа"]=8,["сентября"]=9,["октября"]=10,["ноября"]=11,["декабря"]=12,["-"]=""} local monthd = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} local params = { {"г", "g"}, {"ю", "j"}} local comment = { '<span style="border-bottom: 1px dotted; cursor: help" title="по юлианскому календарю">','</span>'} -- duplicates: -- AST, BST, CST, ECT, IST, MST, PST, SST, local known_tzs = { ACDT='+10:30', ACST='+09:30', ACT ='+08:00', ADT ='-03:00', AEDT ='+11:00', AEST='+10:00', AFT ='+04:30', AKDT='-08:00', AKST ='-09:00', AMST ='+05:00', AMT ='+04:00', ART ='-03:00', AST ='+03:00', AST ='+04:00', AST ='+03:00', AST ='-04:00', AWDT='+09:00', AWST='+08:00', AZOST='-01:00', AZT ='+04:00', BDT ='+08:00', BIOT='+06:00', BIT ='-12:00', BOT ='-04:00', BRT ='-03:00', BST ='+06:00', BST ='+01:00', BTT ='+06:00', CAT ='+02:00', CCT ='+06:30', CDT ='-05:00', CEDT='+02:00', CEST='+02:00', CET ='+01:00', CHAST='+12:45', CIST='-08:00', CKT ='-10:00', CLST='-03:00', CLT ='-04:00', COST ='-04:00', COT ='-05:00', CST ='-06:00', CST ='+08:00', CVT ='-01:00', CXT ='+07:00', CHST='+10:00', DFT ='+01:00', EAST='-06:00', EAT ='+03:00', ECT ='-04:00', ECT ='-05:00', EDT ='-04:00', EEDT='+03:00', EEST ='+03:00', EET ='+02:00', EST ='-05:00', FJT ='+12:00', FKST='-03:00', FKT ='-04:00', GALT ='-06:00', GET ='+04:00', GFT ='-03:00', GILT='+12:00', GIT ='-09:00', GMT ='+00:00', GST ='-02:00', GYT ='-04:00', HADT='-09:00', HAST ='-10:00', HKT ='+08:00', HMT ='+05:00', HST ='-10:00', IRKT='+08:00', IRST ='+03:30', IST ='+05:30', IST ='+01:00', IST ='+02:00', JST ='+09:00', KRAT ='+07:00', KST ='+09:00', LHST='+10:30', LINT='+14:00', MAGT='+11:00', MDT ='-06:00', MIT ='-09:30', MSD ='+04:00', MSK ='+03:00', MST ='+08:00', MST ='-07:00', MST ='+06:30', MUT ='+04:00', NDT ='-02:30', NFT ='+11:30', NPT ='+05:45', NST ='-03:30', NT ='-03:30', OMST='+06:00', PDT ='-07:00', PETT ='+12:00', PHOT ='+13:00', PKT ='+05:00', PST ='-08:00', PST ='+08:00', RET ='+04:00', SAMT ='+04:00', SAST='+02:00', SBT ='+11:00', SCT ='+04:00', SLT ='+05:30', SST ='-11:00', SST ='+08:00', TAHT='-10:00', THA ='+07:00', UTC ='+00:00', UYST ='-02:00', UYT ='-03:00', VET ='-04:30', VLAT='+10:00', WAT ='+01:00', WEDT ='+01:00', WEST='+01:00', WET ='+00:00', YAKT='+09:00', YEKT ='+05:00', -- US Millitary (for RFC-822) Z='+00:00', A='-01:00', M='-12:00', N='+01:00', Y='+12:00', } local category = { ["no_parameters"]= "<!--[[Категория:Модуль:Calendar:Страницы без параметров]]-->", ["incomplete_parameters"]= "<!--[[Категория:Модуль:Calendar:Страницы с неполными или некорректными параметрами]]-->", ["without_verification"]= "<!--[[Категория:Модуль:Calendar:Страницы без проверки параметров]]-->", ["erroneous_parameters"]= "<!--[[Категория:Модуль:Calendar:Страницы с ошибочными параметрами]]-->" } -- несколько параметров передаются вместе с кодом ошибки в таблице, один может быть передан простым значением local e = { ["start"]="<span class=error>Ошибка: ", ["ending"]=".</span>", ["no_pattern_match"]="строка «%s» не совпадает с заданными паттернами", ["no_valid_date"]="дата «%s» не является корректной", ["wrong_jd"]="юлианская дата %s вне диапазона", ["no_data"]="нет входящих данных", ["too_many_arguments"]="ожидается менее %i аргументов", ["too_little_arguments"]="ожидается более %i аргументов", ["wrong_calculation"]="даты %s и %s не прошли проверку, %s дней разница", ["unknown_param"]="параметр %s неизвестен", ["unknown_error"]="неизвестная ошибка", ["tech_error"]="ошибка в функции %s", ["box_date"]="строка «%s» не является верной датой, пожалуйста, укажите дату в формате ГГГГ-ММ-ДД" -- [""]="", } local tzs_names = {"ACDT","ACST","ACT","ADT","AEDT","AEST","AFT","AKDT","AKST", "AMST","AMT","ART","AST","AST","AST","AST","AWDT","AWST","AZOST","AZT","BDT", "BIOT","BIT","BOT","BRT","BST","BST","BTT","CAT","CCT","CDT","CEDT","CEST", "CET","CHAST","CIST","CKT","CLST","CLT","COST","COT","CST","CST","CVT","CXT", "CHST","DFT","EAST","EAT","ECT","ECT","EDT","EEDT","EEST","EET","EST","FJT", "FKST","FKT","GALT","GET","GFT","GILT","GIT","GMT","GST","GYT","HADT","HAST", "HKT","HMT","HST","IRKT","IRST","IST","IST","IST","JST","KRAT","KST","LHST", "LINT","MAGT","MDT","MIT","MSD","MSK","MST","MST","MST","MUT","NDT","NFT", "NPT","NST","NT","OMST","PDT","PETT","PHOT","PKT","PST","PST","RET","SAMT", "SAST","SBT","SCT","SLT","SST","SST","TAHT","THA","UTC","UYST","UYT","VET", "VLAT","WAT","WEDT","WEST","WET","YAKT","YEKT","Z","A","M","N","Y","MSK"} local pattern = { -- для распознавания дат, переданных одним строчным параметром {"(-?%d%d%d%d?)[-%.%s/\\](%d%d)[-%.%s/\\](%d%d)", ["order"] = {3,2,1} }, -- yyyy mm dd {"(%d+)[-%.%s/\\](%d+)[-%.%s/\\](%d%d%d%d?)", ["order"] = {1,2,3} }, -- dd mm yyyy {"(%d%d)[-%.%s/\\](%d%d%d%d?)", ["order"] = {2,3} }, -- mm yyyy {"(%d%d%d%d?)[-%.%s/\\](%d%d)", ["order"] = {3,2} }, -- yyyy mm {"(%d+)%s(%l+)%s(%d%d%d%d?)", ["order"] = {1,2,3} }, -- d mmm y {"(%l+)%s(%d+),?%s(%d%d%d%d?)", ["order"] = {2,1,3} }, -- mmm d, y {"(%l+)%s(%d%d%d%d?)", ["order"] = {2,3} }, -- mmm y } local time_units = {"year","month","day"} --не используется --[[ local time_units = {"second", "minute", "hour", "day_of_month", "day_of_week", "day_of_year", "week", "month", "year", "year_of_century", "century"} ]]-- -- напоминание чтобы сделать более точные пересчёты - с часами / расчёт длительностей периодов local mnlang = {"ru_G", "ru_N", "en", "en_S", "de", "fr"} local month_lang = { ["ru_G"] = {"января","февраля","марта","апреля","мая","июня", "июля","августа","сентября","октября","ноября","декабря"}, ["ru_N"] = {"январь","февраль","март","апрель","май","июнь", "июль","август","сентябрь","октябрь","ноябрь","декабрь"}, ["en"] = {"january", "february", "march", "april", "may", "june", "july", "august", "september", "october", "november", "december"}, ["en_S"] = {"jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec"}, ["de"] = {"januar", "februar", "märz", "april", "mai", "juni", "juli", "august", "september", "oktober", "november", "dezember"}, ["fr"] = {"janvier", "février", "mars", "avril", "mai", "juin", "juillet", "août", "septembre", "octobre", "novembre", "décembre"} } -- заполняется автоматически local reverse_month_lang = {} -- вспомогательная функция для обращения таблиц (смена ключей со значениями) local reverse_table = function (strait_table) local reversed_table = {} for k,v in pairs(strait_table) do reversed_table[v] = k end return reversed_table end -- запуск цикла по заполнению обратных таблиц, необходимых для распознавания дат local filling_months = function (mnlang, month_lang) for i=1, #mnlang do reverse_month_lang[mnlang[i]] = reverse_table(month_lang[mnlang[i]]) end end -- 10) Блок общих функций local function trim(str) if not str then return nil else return str:match'^()%s*$' and '' or str:match'^%s*(.*%S)' end end local function purif(str) if str == "" or str == nil then return nil elseif type(tonumber(str)) == "number" then return math.floor(tonumber(str)) else return nil end -- need .5 -- ,5 number format converter? end local function is(str) if (not str) or (str == "") then return false else return yesno(str,false) end end local function init(num) local output = {} for i=1,num do table.insert(output, {["year"]="", ["month"]="", ["day"]=""}) end return unpack(output) end local function isyear(tbl) if type(tbl) ~= 'table' then return false elseif not tbl["year"] then return false elseif type(tbl["year"]) == 'number' then return true else return false end end local function inbord(val, down, up) return not (type(up) ~= "number" or type(down) ~= "number" or type(val) ~= "number" or up < down or val < down or val > up) end local function shallowcopy(orig) local orig_type = type(orig) local copy if orig_type == 'table' then copy = {} for orig_key, orig_value in pairs(orig) do copy[orig_key] = orig_value end else -- number, string, boolean, etc copy = orig end return copy end local inlist = function ( var, list ) local n = #list local inlist = false for i=1,n do if var == list[i] then inlist = true end end return inlist end -- 20) Блок общих проверочных функций, связанных с датами local function unwarp(tbl) if not tbl then return "" elseif type(tbl) ~= "table" then return tbl elseif (tbl.day or tbl.month or tbl.year) then return (tbl.year or "?").."-"..(tbl.month or "?").."-"..(tbl.day or "?") else return (tbl[3] or "?").."-"..(tbl[2] or "?").."-"..(tbl[1] or "?") end end local function leap_year(y,jul) if (not y) or (type(y) ~= "number") then return false elseif (y % 4) ~= 0 then return false elseif not jul and (y % 100 == 0 and y % 400 ~= 0) then return false else return true end end -- функция для вычисления последнего дня месяца для юлианского и григорианского календарей local function month_end_day (month,year,is_julian) local month_end_day = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} -- если не задан год, дата 29 февраля считается допустимой if not month or type(month) ~= "number" or month < 1 or month > 12 then return nil elseif month ~= 2 or not year then return month_end_day[month] elseif month == 2 and (year % 4) == 0 and not ((not is_julian) and (year % 100 == 0 and year % 400 ~= 0)) then return 29 elseif month == 2 then return 28 else return nil -- в случае не целого значения входящих параметров или при иных непредусмотренных событиях end end local function isdate ( chain , jul ) -- можно использовать для проверки таблиц с полями day, month, year if not chain then return false elseif (not type(chain) == "table") or (not inbord(chain.year,-9999,9999)) or (not inbord(chain.month,1,12)) or (not inbord(chain.day,1,31)) or chain.day > monthd[chain.month] -- or chain.year == 0 then return false elseif chain.month == 2 and chain.day == 29 and not leap_year(chain.year,jul) then return false else return true end -- check for other calendars needed? end local function ispartdate ( chain ) if not chain then return false elseif not (type(chain) == "table") then return false elseif (inbord(chain.year,-9999,9999) or inbord(chain.month,1,12) or inbord(chain.day,1,31)) then return true else return false end -- partial date -- more detailed check for 31.02.0000 needed -- check for other calendars needed end -- from date1 to date2 in one year (beetwen jan-dec, dec-jan needed) local function partdist(date1,date2) local mont, dist = 0, 0 local d1d, d1m, d2d, d2m = (date1["day"] or ""), (date1["month"] or ""),(date2["day"] or ""), (date2["month"] or "") if not (inbord(d1d,1,31) and inbord(d2d,1,31)) then return false end -- нужна доп. проверка частичных дат на корректность if (inbord(d1m,1,12) or inbord(d2m,1,12)) and (d1m == "" or d2m == "") then mont = purif(date1["month"] or date2["month"]) d1m, d2m = mont, mont end -- mw.log("📏 day: " ..d1d .."->"..d2d.." month: ".. d1m.."->"..d2m ) if (inbord(d1m,1,12) and d1d <= monthd[d1m]) and (inbord(d2m,1,12) and d2d <= monthd[d2m]) then if d2m == d1m then dist = d2d - d1d else dist = monthd[d1m] - d1d + d2d end return dist else return math.huge end end local function dmdist(d1,d2) local p1,p2 = math.huge,math.huge if not not partdist(d1,d2) then p1=partdist(d1,d2) end if not not partdist(d2,d1) then p1=partdist(d2,d1) end -- if (not p1) or (not p2) then -- return (p1 or "") .. (p2 or "") -- else -- mw.log("d1, d2 = " .. undate(d1) .. ", " .. undate(d2)) return math.min(tonumber(partdist(d1,d2)) or math.huge,tonumber(partdist(d2,d1)) or math.huge) -- end end -- 30) Блок функций для обработки ввода-вывода дат local function undate(tbl) if not tbl then return "" else return (tbl.year or "").."-"..(tbl.month or "").."-"..(tbl.day or "") end end -- функция для нормализации значений дат и перевода месяцев в числа local function numerize(str) if type(str) == "number" then return math.floor(str) elseif str == "" or str == nil or type(str) ~= "string" then return nil elseif type(tonumber(str)) == "number" then return math.floor(tonumber(str)) else for i=1, #mnlang do if inlist(mw.ustring.lower(str),month_lang[mnlang[i]]) then return reverse_month_lang[mnlang[i]][mw.ustring.lower(str)] end end end end -- функция распознавания даты, переданной одной строкой local function parse_date(date_string) if type(date_string) ~= "string" or date_string == "" then return nil end local out_date_str = {"","",""} local error_data = {} for i=1, #pattern do local result_1, result_2, result_3 = mw.ustring.match(mw.ustring.lower(date_string),pattern[i][1]) if (result_1 or "") > "" then out_date_str[pattern[i].order[1]] = result_1 out_date_str[pattern[i].order[2]] = result_2 if (pattern[i].order[3]) then out_date_str[pattern[i].order[3]] = result_3 end -- mw.log("Паттерн " .. i .. ", строка: " .. date_string) break end end local date = { ["day"] =numerize(out_date_str[1]), ["month"]=numerize(out_date_str[2]), ["year"] =numerize(out_date_str[3])} return date --, error_data end ----[[ УСТАРЕЛО ]]---- local numstr2date = function(numstr) local format = "Y-m-d" local iso_date = mwlang:formatDate(format,numstr) local y,m,d = string.match(iso_date, "(%d+)-(%d+)-(%d+)") local dateout = {["year"]=purif(y), ["month"]=purif(m), ["day"]=purif(d)} return dateout end --local numstr2date = function(numstr) -- local nums = {} -- local dateout = {} -- for num in string.gmatch(numstr,"(%d+)") do -- table.insert(nums,purif(num)) -- end -- if #nums ~= 3 then error("В поле даты вместо трёх чисел с разделителями указано " .. #nums) -- elseif not inbord(nums[2],1,12) then error("Месяц с номером " .. nums[2] .. " не найден") -- elseif not inbord(nums[3],1,31) then -- dateout = {["year"]=nums[3], ["month"]=nums[2], ["day"]=nums[1]} -- elseif not inbord(nums[1],1,31) then -- dateout = {["year"]=nums[1], ["month"]=nums[2], ["day"]=nums[3]} -- elseif inbord(nums[1],1,31) then -- dateout = {["year"]=nums[3], ["month"]=nums[2], ["day"]=nums[1]} -- else -- local mwlang = mw.getContentLanguage() -- implement mwlang:formatDate(format,datein,true) here -- return error("Не распознано " .. numstr .. " как дата") -- end -- return dateout --end local function year2lang(numyear,yearmark,wiki) if not numyear then return "" end if not yearmark then yearmark = "" end local output = "" local bcmark = " до н. э." if numyear > 0 then bcmark = "" else numyear = 1 - numyear end if wiki then -- output = tCon({'[[', numyear,' год',bcmark,'|', numyear,']]', " ", yearmark, " ", bcmark}) output = tCon({'[[', numyear,' год',bcmark,'|', trim(numyear .. " " .. yearmark .. " " .. bcmark), ']]'}) else output = tCon({numyear, " ", yearmark, bcmark}) end return trim(output) end local function day2lang(datein,wikidate,wiki,inner_brt) -- if not isdate(wikidate) then wiki = false end if not ispartdate(datein) then return "" end local dm_separ, output = "", nil if (not (not datein.day)) and (not (not datein.month)) then dm_separ = " " end if (not datein.month) then datein.month = "" end if (not datein.day) then datein.day = "" end local monlan = monthlang[datein.month] or "" if wiki and not inner_brt then output = tCon({"[[", wikidate.day, " ", monthlang[wikidate.month] or "", "|", (datein.day or ""), dm_separ, monlan, "]]"}) elseif wiki then output = tCon({"[[", wikidate.day, " ", monthlang[wikidate.month] or "", "|", (datein.day or ""), dm_separ, monlan}) else output = tCon({datein.day, dm_separ, monlan}) end return trim(output) end local function triple_txt2date(d,m,y) -- добавить (args[1]:match("(%a+)") or "-") для нестандартной записи -- mw.ustring.match((m or ""),"(%a+)") local msg = "" local year = purif((y or "-"):match("(%d+)")) local month = purif(month_to_num[string.lower(mw.ustring.match((m or ""),"(%a+)"))]) local day = purif((d or "-"):match("(%d+)")) if not month then msg = category.incomplete_parameters month = purif(month_to_num[string.lower(mw.ustring.match((d or ""),"(%a+)") or "-")]) end if (not day) and ((purif(string.match(m or "","(%d+)") or "") or 32) <= (monthd[month] or 31)) then msg = category.incomplete_parameters day = purif(m:match("(%d+)") or "") end if not year then msg = category.incomplete_parameters year = purif(string.match(m or "","(%d+)") or "") end local dateout = {["year"]=year, ["month"]=month, ["day"]=day, ["msg"]=msg} return dateout end local function glue(d1,m1,y1,d2,m2,y2) if (not d1) and (not m1) and (not y1) and (not d2) and (not m2) and (not y2) then return category.incomplete_parameters end local gd,gm,gy,jd,jm,jy = (d1 or ""), (m1 or ""), (y1 or ""), (d2 or ""), (m2 or ""), (y2 or "") --mw.log(tCon({gd,gm,gy,jd,jm,jy})) local gm_sep = {" [["," год|","]]"} if (not gy) or (gy == "") then gm_sep = {"","",""} end return tCon({comment[1],trim(trim(jd .. " " .. jm) .. " " .. jy ), comment[2]," ([[",trim(gd .. " " .. gm),"]]",gm_sep[1],(gy:match("(%d+)") or ""), gm_sep[2],gy,gm_sep[3],")",category.incomplete_parameters}) end -- добавить отображение без года local function double_couple(jdate, gdate, wd, wm, wy, sq_brts, yearmark) local msg = "" msg = (jdate.msg or "") .. (gdate.msg or "") local cd = {} local jd = shallowcopy(jdate) local gd = shallowcopy(gdate) local left = "(" local right = ")" if sq_brts then left = "&#091;" right = "&#093;" end if (not isdate(jdate,true)) then return error((jdate.day or "") .. "." .. (jdate.month or "") .."." .. (jdate.year or "") .. " неподходящая дата") elseif (not isdate(gdate)) then return error((gdate.day or "") .. "." .. (gdate.month or "") .."." .. (gdate.year or "") .. " неподходящая дата") end if jd.year == gd.year then cd.year = gd.year gd.year, jd.year = nil, nil end if jd.month == gd.month then cd.month = gd.month gd.month, jd.month = nil, nil end if (not not cd.month) and wm then return tCon({comment[1] .. trim(day2lang(jd,jdate,false) .. " " .. year2lang(jd.year,yearmark,false)) .. comment[2], trim(left .. day2lang(gd,gdate,wd,wm) .. " " .. year2lang(gd.year,yearmark,wy)) .. right, day2lang(cd,gdate,false) .. "]]", trim(year2lang(cd.year,yearmark,wy)..msg)}, " ") end return tCon({comment[1] .. trim(day2lang(jd,jdate,false) .. " " .. year2lang(jd.year,yearmark,false)) .. comment[2], trim(left .. day2lang(gd,gdate,wd) .. " " .. year2lang(gd.year,yearmark,wy)) .. right, trim(day2lang(cd,gdate,false)), trim(year2lang(cd.year,yearmark,wy)..msg)}, " ") end -- 40) Блок функций для перевода дат с использованием [[Юлианская дата]] local function gri2jd( datein ) if not isdate(datein) then return error((datein.day or "") .. "." .. (datein.month or "") .."." .. (datein.year or "") .. " неподходящая дата") end local year = datein.year local month = datein.month local day = datein.day -- jd calculation local a = math.floor((14 - month)/12) local y = year + 4800 - a local m = month + 12*a - 3 local offset = math.floor(y/4) - math.floor(y/100) + math.floor(y/400) - 32045 local jd = day + math.floor((153*m + 2)/5) + 365*y + offset -- jd validation local low, high = -1931076.5, 5373557.49999 if not (low <= jd and jd <= high) then return error((datein.day or "") .. "." .. (datein.month or "") .. "." .. (datein.year or "") .. " выходит за пределы разрешённого диапазона") end return jd end local function jd2jul( jd ) if type(jd) ~= "number" then return error("Промежуточная переменная " .. (jd or "") .. " не является числом") end -- calendar date calculation local c = jd + 32082 local d = math.floor((4*c + 3)/1461) local e = c - math.floor(1461*d/4) local m = math.floor((5*e + 2)/153) local year_out = d - 4800 + math.floor(m/10) local month_out = m + 3 - 12*math.floor(m/10) local day_out = e - math.floor((153*m + 2)/5) + 1 -- output local dateout = {["year"]=year_out, ["month"]=month_out, ["day"]=day_out} return dateout end local function jul2jd( datein ) if not isdate(datein,true) then return error((datein.day or "") .. "." .. (datein.month or "") ..".".. (datein.year or "") .. " неподходящая дата") end local year = datein.year local month = datein.month local day = datein.day -- jd calculation local a = math.floor((14 - month)/12) local y = year + 4800 - a local m = month + 12*a - 3 local offset = math.floor(y/4) - 32083 local jd = day + math.floor((153*m + 2)/5) + 365*y + offset -- jd validation local low, high = -1930999.5, 5373484.49999 if not (low <= jd and jd <= high) then return error((datein.day or "") .. "." .. (datein.month or "") .."." .. (datein.year or "") .. " выходит за пределы разрешённого диапазона") end return jd end local function jd2gri( jd ) if type(jd) ~= "number" then return error("Промежуточная переменная " .. (jd or "") .. " не является числом") end -- calendar date calculation local a = jd + 32044 local b = math.floor((4*a + 3) / 146097) local c = a - math.floor(146097*b/4) local d = math.floor((4*c+3)/1461) local e = c - math.floor(1461*d/4) local m = math.floor((5*e+2)/153) local day_out = e - math.floor((153*m+2)/5)+1 local month_out = m + 3 - 12*math.floor(m/10) local year_out = 100*b + d - 4800 + math.floor(m/10) -- output local dateout = {["year"]=year_out, ["month"]=month_out, ["day"]=day_out} return dateout end local function astroyear(num, bc) if not num then return error() elseif type(num) ~= "number" then return error() end if num < 1 then return num end if not bc then return num else return 1 - num end end local function recalc(datein,calend) if inlist(calend,params[1]) then return jd2jul(gri2jd(datein)), datein elseif inlist(calend,params[2]) then return datein, jd2gri(jul2jd(datein)) else error("Параметр " .. (calend or "") .. " не опознан, разрешённые: " .. tCon(params[1]," ") .. " и " .. tCon(params[2]," ")) end end -- 50) Функции для обработки UTC local function utc(str,margin) local d = 1 local dchar = "+" local beginning = "[[UTC" local ending = "]]" local cat = "" local nums = {} local hmarg, timedec = 0, 0 local mmarg = "00" local output = "" -- checking type of input if not margin then margin = 0 elseif type(tonumber(margin)) ~= 'number' then output = "Can't shift by " .. margin error(output) end if type(str) ~= 'string' then error("Нет входящей строки") elseif str:byte(1) == 43 then elseif inbord(str:byte(1),48,57) then cat = "[[Категория:Википедия:Ошибка в часовом поясе НП]]" elseif str:byte(1) == 45 or string.sub(str,1,3) == "−" or string.sub(str,1,1)=="-" then d = -1 else error(string.char(str:byte(1)) .. " недопустимый первый символ") end -- parsing input for num in string.gmatch(str,"(%d+)") do table.insert(nums,purif(num)) end if #nums > 2 then error("Ожидается всего 2 числа, а не " .. #nums) elseif #nums == 0 then error("Необходимо что-то ввести") elseif #nums == 1 then if inbord(nums[1],0,14) then timedec = d*nums[1] + margin else error("Только часы от -14 до 14") end elseif #nums == 2 then if not inbord(nums[1],0,14) then error("Только часы от -14 до 14") elseif not inbord(nums[2],0,59) then error("Минуты только от 0 до 59") else timedec = d*(nums[1] + nums[2]/60) + margin end end if tonumber(timedec) == purif(timedec) then hmarg = timedec else local h, m = math.modf(math.abs(timedec)) hmarg = h mmarg = math.floor(m*60) end if timedec == 0 then dchar = "±" elseif timedec > 0 then elseif timedec < 0 then dchar = "&minus;" end -- output output = beginning .. dchar .. math.abs(hmarg) .. ":" .. string.format("%02d",mmarg) .. ending .. cat return output end -- 60) Блок функций ввода-вывода function p.NthDay( frame ) local args = getArgs(frame, { frameOnly = true }) local num, wday, mont, yea, format = purif(args[1]), purif(args[2]), purif(args[3]), purif(args[4]), args[5] if not format then format = "%d.%m.%y" end if not inbord(num,-5,5) then return error("The number must be between -5 and 5") elseif num == 0 then return error("The number must not be zero") end if not inbord(wday,0,6) then return error("The day of the week must be between 0 and 6") end if not inbord(mont,1,12) then return error("The month must be between 1 and 12") end if not inbord(yea,0,9999) then return error("Wrong year number") end if inbord(num,1,5) then local m_start = os.time{year=yea, month=mont, day=1, hour=0} local m_wds = tonumber(os.date("%w", m_start)) local start_shift = ( (num - bool_to_number[wday >= m_wds]) * 7 - (m_wds - wday) ) * 24 * 60 * 60 local tim = m_start + start_shift if tonumber(os.date("%m", tim)) == mont then return (os.date(format, tim)) else return (err) end elseif inbord(num,-5,-1) then local m_end = os.time{year = yea, month = mont + 1, day = 1, hour = 0} - 24 * 60 * 60 local m_wde = tonumber(os.date("%w", m_end)) local end_shift = ((math.abs(num + 1) + bool_to_number[wday > m_wde]) * 7 + (m_wde - wday)) * 24 * 60 * 60 local tim = m_end - end_shift if tonumber(os.date("%m", tim)) == mont then return (os.date(format, tim)) else return (err) end end end -- =p.ToIso(mw.getCurrentFrame():newChild{title="smth",args={"12 декабря 2020"}}) -- =p.ToIso(mw.getCurrentFrame():newChild{title="smth",args={"1.2.1602"}}) -- =p.ToIso(mw.getCurrentFrame():newChild{title="smth",args={"12.12.2021"}}) -- =p.ToIso(mw.getCurrentFrame():newChild{title="smth",args={"2021.12.12"}}) function p.ToIso( frame ) local args = getArgs(frame, { frameOnly = true }) local datein = args[1] -- инициализация, заполнение обратных таблиц, копирование параметров filling_months(mnlang, month_lang) -- парсинг входящей даты по шаблону local date = parse_date(datein) if not (type(date.year) == 'number') then return ("Wrong year: " .. unwarp(date)) end if not (1 <= date.month and date.month <= 12) then return ("Wrong month: " .. unwarp(date)) end if not date.day or not (1 <= date.day and date.day <= month_end_day(date.month,date.year)) then return ("Wrong day: " .. unwarp(date)) end local timedate = os.time{year=date.year, month=date.month, day=date.day} local date = os.date("%Y-%m-%d", timedate) return date end -- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"12 декабря 2020"}}) -- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"1.2.1602"}}) -- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"декабрь 2020"}}) -- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"12-2020"}}) -- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"12.12.2021"}}) -- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"2021.12.12"}}) -- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"2021.11"}}) -- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"11.2021"}}) function p.BoxDate( frame ) local args = getArgs(frame, { frameOnly = true }) local txtDateIn, strFormat = args[1], args[2] local txtDateOut, date, status = p.bxDate(txtDateIn, strFormat, params) if status.brk then return error(status.errorText) else return txtDateOut end end function p.bxDate( txtDateIn , strFormat, params ) -- к отладке local txtDateOut, date, status = "", {}, {brk = false, errorCat = "", errorText = ""} strFormat = strFormat or "j xg Y" -- заглушка - таблица параметров на будущее params = params or {} if not txtDateIn then status.errorText = e.no_data status.errorCat = category.no_parameters status.brk = true else -- заполнение служебных таблиц filling_months(mnlang, month_lang) end if not status.brk then -- парсинг входящей даты по шаблону date = parse_date(txtDateIn) -- заменить сообщения об ошибках на списочные if not (date.year and type(date.year) == 'number') then status.errorText = string.format(e.box_date,txtDateIn) status.errorCat = category.incomplete_parameters status.brk = true end if not inbord(date.month,1,12) then status.errorText = string.format(e.box_date,txtDateIn) status.errorCat = category.incomplete_parameters status.brk = true end if not date.day and string.find(strFormat,"[dDjlNwzW]") then strFormat = trim(string.gsub(string.gsub(strFormat,"xg","F"),"[dDjlNwzW]","")) elseif not date.day then elseif not inbord(date.day,1,month_end_day(date.month,date.year)) then status.errorText = string.format(e.box_date,txtDateIn) status.errorCat = category.incomplete_parameters status.brk = true end end if not status.brk then txtDateOut = mwlang:formatDate(strFormat,tCon({date.year,date.month,date.day},"-"),true) end return txtDateOut, date, status end function p.ToDate( frame ) -- возможно неиспользуемая local args = getArgs(frame, { frameOnly = true }) local mwlang = mw.getContentLanguage() local datein = args[1] local format = "j xg Y" if not string.match(datein, "%p") then return datein elseif not args[2] then else format = args[2] end return mwlang:formatDate(format,datein,true) end -- =p.unitime(mw.getCurrentFrame():newChild{title="smth",args={"−1:30","1"}}) function p.unitime( frame ) local args = getArgs(frame, { frameOnly = true }) local DST = 0 if not args[2] then else DST = 1 end local utcin = "" local input = args[1] if not input then return "" end if inlist(input:upper(),tzs_names) then utcin = known_tzs[input:upper()] elseif (string.sub(input:upper(),1,3) == 'UTC') and (string.len(input) < 10) then utcin = string.sub(input,4) else if string.sub(input,1,1) == '[' or string.sub(input,1,1) == '{' or string.sub(input,1,1):upper() == 'U' or string.sub(input,1,1):upper() == 'M' then return input -- elseif not string.find(string.upper(string.sub(input,1,1)),"[\65-\90]") or -- not string.find(string.upper(string.sub(input,1,1)),"[\192-\223]") then -- return input else utcin = input end end -- elseif string.sub(input,1,3) ~= "−" then utcin = input -- or not (not input:find("[А-я]")) при наличии в строке юникода не работает local output = "" if DST == 0 then output = utc(utcin) else output = utc(utcin) .. ", [[летнее время|летом]] " .. utc(utcin,DST) end return output end -- УСТАРЕЛО -- =p.OldDate(mw.getCurrentFrame():newChild{title="smth",args={"20.02.2020","ю",["bc"]="1",["wd"]="1",["wy"]="1",["sq_brts"]="1",["yearmark"]="г."}}) function p.OldDate( frame ) local args = getArgs(frame, { frameOnly = true }) if not args[1] then return err end local gdate, jdate = {}, {} local strin = args[1] local cal = args[2]:lower() or "г" local bc = is(args["bc"]) local wd = is(args["wd"]) local wm = is(args["wm"]) local wy = is(args["wy"]) if not wd then wm = false end local sq_brts = is(args["sq_brts"]) local yearmark = "года" if yesno(args["yearmark"]) then elseif yesno(args["yearmark"]) == false then yearmark = "" else yearmark = trim(args["yearmark"]) or "года" end -- local infocard = is(args["infocard"]) -- local catName = args["catName"] or false local datein = numstr2date(strin) datein.year = astroyear(datein.year, bc) jdate, gdate = recalc(datein,cal) return double_couple(jdate, gdate, wd, wm, wy, sq_brts, yearmark) end -- =p.NewDate(mw.getCurrentFrame():newChild{title="Salt",args={"2020-02-20"}}) -- =p.NewDate(mw.getCurrentFrame():newChild{title="smth",args={"20.02.2020","ю",["bc"]="1",["wd"]="1",["wy"]="1",["sq_brts"]="1",["yearmark"]="г."}}) -- =p.NewDate(mw.getCurrentFrame():newChild{title="smth",args={"20.02.2020",["bc"]="0",["wd"]="1",["wy"]="1",["sq_brts"]="0",["yearmark"]=""}}) function p.NewDate( frame ) local args = getArgs(frame, { frameOnly = true }) if not args[1] then return err end local strin = args[1] local year, month, day if not not strin:match( "(-?%d%d%d%d%d)-(%d%d)-(%d%d)" ) then year, month, day = strin:match( "(-?%d%d%d%d%d)-(%d%d)-(%d%d)" ) elseif not not strin:match( "(-?%d+)-(%d+)-(%d+)" ) then year, month, day = strin:match( "(-?%d+)-(%d+)-(%d+)" ) elseif not not strin:match( "(%d%d)%.(%d%d)%.(-?%d%d%d%d%d)" ) then day, month, year = strin:match( "(%d%d)%.(%d%d)%.(-?%d%d%d%d%d)" ) elseif not not strin:match( "(%d+)%.(%d+)%.(-?%d+)" ) then day, month, year = strin:match( "(%d+)%.(%d+)%.(-?%d+)" ) end if not year then return error(args[1] .. " не подходит под форматы yyyy-mm-dd или dd.mm.yyyy") end local cal = "г" if (not args[2]) or (args[2] == "") then cal = "г" else cal = args[2]:lower() end local bc,wd,wm,wy,sq_brts = is(args["bc"]), is(args["wd"]), is(args["wd"]) and is(args["wm"]), is(args["wy"]), is(args["sq_brts"]) year = astroyear(purif(year),bc) local datein = {["year"]=purif(year), ["month"]=purif(month), ["day"]=purif(day)} local jdate, gdate = recalc(datein,cal) local yearmark = "года" local ym = args["yearmark"] or "" if yesno(ym) then elseif yesno(ym) == false then yearmark = "" else if not not ym:match("(%d+)") then error("Цифры в обозначении года: " .. ym) else yearmark = trim(ym) or "года" end end return double_couple(jdate, gdate, wd, wm, wy, sq_brts, yearmark) end -- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={}}) -- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"3","июня",nil,"21","мая"}}) -- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"28 августа","","1916 года","15"}}) -- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"3","июня","1900","21","мая"}}) -- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"6","июня","1889 год","25","мая"}}) -- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"28","ноября","1917","15"}}) -- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"28 августа","nil","1916 года","15"}}) -- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"4","января","1915","22","декабря","1914 года"}}) -- {{OldStyleDate|день (НС)|месяц (НС)|год (НС)|день (СС)|месяц (СС)|год (СС)}} function p.Test( frame ) local args = getArgs(frame, { frameOnly = true }) -- необходима проверка и замена nil на " " --[[mw.log((args[1] or "") .. " " .. (args[2] or "") .. " " .. (args[3] or "") .. " " .. (args[4] or "") .. " " .. (args[5] or "") .. " " .. (args[6] or "")) ]]-- local ingdate = triple_txt2date(args[1],args[2],args[3]) local injdate = triple_txt2date(args[4],args[5],args[6]) local j1date, g1date, j2date, g2date = init(4) mw.log("ingdate-".. (undate(ingdate) or "")) mw.log("injdate-".. (undate(injdate) or "")) local bc,wd,wm,wy,sq_brts,ny = is(args["bc"]), is(args["wd"]), is(args["wd"]) and is(args["wm"]), is(args["wy"]), is(args["sq_brts"]), is(args["ny"]) -- подавление формата для локальных тестов local wd, wm, wy = true, true, true local yearmark = "года" local ym = args["yearmark"] or ((mw.ustring.match((args[3] or ""),"(%a+)") or mw.ustring.match((args[6] or ""),"(%a+)")) or "") -- mw.log("ym " .. ym) if yesno(ym) then elseif yesno(ym) == false then yearmark = "" else if not not ym:match("(%d+)") then error("Цифры в обозначении года: " .. ym) else yearmark = trim(ym) or "года" end end if isdate(ingdate) or isdate(injdate) then if isdate(ingdate) then j1date, g1date = recalc(ingdate,"g") ingdate["full"] = true end if isdate(injdate) then j2date, g2date = recalc(injdate,"j") injdate["full"] = true end if ispartdate(ingdate) and ispartdate(injdate) then mw.log("📏 " .. dmdist(ingdate,injdate)) mw.log("📏 " .. dmdist(j1date,g1date)) mw.log("📏 " .. dmdist(j2date,g2date)) mw.log("📏 " .. dmdist(ingdate,g1date)) mw.log("📏 " .. dmdist(injdate,j2date)) end end if ny then if isyear(j1date) then else j1date["year"] = "" end if isyear(j2date) == nil then else j2date["year"] = "" end if isyear(g1date) == nil then else g1date["year"] = "" end if isyear(g2date) == nil then else g2date["year"] = "" end end if (isdate(j1date) and isdate(g1date) and isdate(j2date) and isdate(g2date)) then if ((j1date.year == j2date.year) and (j1date.month == j2date.month) and (j1date.day == j2date.day)) then return double_couple(j1date, g1date, wd, wm, wy, sq_brts, yearmark) else mw.log("📏 " .. (tostring(dmdist(ingdate,injdate)) or "")) return glue(args[1],args[2],args[3],args[4],args[5],args[6]) -- категория (предположительная разница в днях) и частичный вывод end elseif isdate(j1date) and isdate(g1date) then return double_couple(j1date, g1date, wd, wm, wy, sq_brts, yearmark) -- категория плюс частичная проверка elseif isdate(j2date) and isdate(g2date) then return double_couple(j2date, g2date, wd, wm, wy, sq_brts, yearmark) -- категория плюс частичная проверка elseif (ispartdate(ingdate) and ispartdate(injdate)) then mw.log("ingdate ".. (undate(ingdate) or "")) mw.log("injdate ".. (undate(injdate) or "")) mw.log("j1date " .. (undate(j1date ) or "")) mw.log("j2date " .. (undate(j2date ) or "")) mw.log("g1date " .. (undate(g1date ) or "")) mw.log("g2date " .. (undate(g2date ) or "")) mw.log("📏 " .. (tostring(partdist(ingdate,injdate)) or "").. " — " .. (tostring(partdist(injdate,ingdate)) or "")) return glue(args[1],args[2],args[3],args[4],args[5],args[6]) -- частичный или полный вывод, категория else mw.log("ingdate ".. (undate(ingdate) or "")) mw.log("injdate ".. (undate(injdate) or "")) mw.log("j1date " .. (undate(j1date ) or "")) mw.log("j2date " .. (undate(j2date ) or "")) mw.log("g1date " .. (undate(g1date ) or "")) mw.log("g2date " .. (undate(g2date ) or "")) return err .. category.incomplete_parameters end end return p a4a91f134ad3e3b246b3a6681a4ae438da766df4 Модуль:Infocards 828 277 715 2023-05-29T15:51:46Z ruwiki>Putnik 0 переиспользование функции форматирования из [[Module:Dates]] для унификации Scribunto text/plain local infocards = {} local calculateAge = true local dateCat = require( 'Module:Infocards/dateCat' ) local moduleDates = require( 'Module:Dates' ) --[[ Helper function that populates the argument list given that user may need to use a mix of named and unnamed parameters. This is relevant because named parameters are not identical to unnamed parameters due to string trimming, and when dealing with strings we sometimes want to either preserve or remove that whitespace depending on the application. ]] function infocards._getParameters( frame_args, arg_list ) local new_args = {} local index = 1 local value for i,arg in ipairs( arg_list ) do value = frame_args[arg] if value == nil then value = frame_args[index] index = index + 1 end new_args[arg] = value end return new_args end function infocards.isBlank( someString ) return someString == nil or mw.ustring.match(someString, '^%s*$') ~= nil end function infocards.isDate ( frame ) local new_args = infocards._getParameters( frame.args, {'s', 't', 'f'} ) local s = new_args['s'] or '' local t = new_args['t'] or '' local f = new_args['f'] or '' local result = infocards.isDateImpl ( s ) if (result) then return t else return f end end function infocards.isDateImpl ( s ) local converted = infocards.convertToDate ( s ) return converted ~= nil end function infocards.dateOfBirth( frame ) local new_args = infocards._getParameters( frame.args, {'dateOfBirth', 'dateOfDeath', 'suppressAge', 'nocat'} ) local dateOfBirth = new_args['dateOfBirth'] or '' local dateOfDeath = new_args['dateOfDeath'] or '' local suppressAge = new_args['suppressAge'] or '' local nocat = new_args['nocat'] or mw.title.getCurrentTitle().nsText return infocards.dateOfBirthImpl( dateOfBirth, dateOfDeath, suppressAge, nocat ) end function infocards.dateOfBirthImpl( dateOfBirth, dateOfDeath, suppressAge, nocat ) local appendToCategory = infocards.isBlank( nocat ) if ( infocards.isBlank( dateOfBirth ) ) then if ( appendToCategory ) then return dateCat.categoryNoBirthDate else return '' end end if ( mw.ustring.match( dateOfBirth, '^%s*неизвестн.%s*$' ) ~= nil or mw.ustring.match( dateOfBirth, '^%s*%?%s*$' ) ~= nil ) then if ( appendToCategory ) then return "''неизвестно''" .. dateCat.categoryUnknownBirthDate else return "''неизвестно''" end end local appendAge = not (suppressAge ~= '' or not calculateAge) and infocards.isBlank( dateOfDeath ) local parsedDate = infocards.convertToDate ( dateOfBirth ) if ( parsedDate == nil ) then --[[ Temporary hack in order to enable export dates to wikidata ]] local bDateStart = '<span class="no-wikidata" data-wikidata-property-id="P569">' local bDateEnd = '</span>' if ( appendToCategory ) then return bDateStart .. dateOfBirth .. bDateEnd .. dateCat.categoryManualWikification else return bDateStart .. dateOfBirth .. bDateEnd end end local result = infocards.formatDateImpl ( parsedDate, 'bday', appendToCategory and 'Родившиеся' or nil ) if ( appendAge ) then -- TODO: месяцы и дни для (нескольких) новорождённых (см. новейшие [[Категория:Родившиеся в ГГГГ году]]) local age = infocards.age ( parsedDate, os.date("*t") ) if ( age and age < 125) then result = result .. ' <span class="nowrap">(' .. age .. ' ' .. mw.language.new( 'ru' ):plural( age, 'год', 'года', 'лет') .. ')</span>' end if ( appendToCategory ) then if (not age and parsedDate and parsedDate.year ) then age = os.date('*t').year - parsedDate.year -- при неточной дате end if ( age ) then if ( age > 115 ) then result = result .. dateCat.categoryBigCurrentAge elseif ( age >= 0 ) then result = result .. dateCat.categoryBiographiesOfLivingPersons else result = result .. dateCat.categoryNegativeAge end end end end return result end function infocards.dateOfDeath( frame ) local new_args = infocards._getParameters( frame.args, {'dateOfBirth', 'dateOfDeath', 'nocat'} ) local dateOfBirth = new_args['dateOfBirth'] or '' local dateOfDeath = new_args['dateOfDeath'] or '' local nocat = new_args['nocat'] or mw.title.getCurrentTitle().nsText return infocards.dateOfDeathImpl( dateOfBirth, dateOfDeath, nocat ) end function infocards.dateOfDeathImpl( dateOfBirth, dateOfDeath, nocat ) if ( infocards.isBlank( dateOfDeath ) ) then return '' end local appendToCategory = infocards.isBlank( nocat ) if ( mw.ustring.match( dateOfDeath, '^%s*неизвестн.%s*$' ) ~= nil or mw.ustring.match( dateOfDeath, '^%s*%?%s*$' ) ~= nil ) then if ( appendToCategory ) then return "''неизвестно''" .. dateCat.categoryUnknownDeathDate else return "''неизвестно''" end end local parsedDateOfBirth = infocards.convertToDate ( dateOfBirth ) local parsedDateOfDeath = infocards.convertToDate ( dateOfDeath ) if ( parsedDateOfDeath == nil ) then --[[ Temporary hack in order to enable export dates to wikidata ]] local dDateStart = '<span class="no-wikidata" data-wikidata-property-id="P570">' local dDateEnd = '</span>' if ( appendToCategory ) then return dDateStart .. dateOfDeath .. dDateEnd .. dateCat.categoryManualWikification else return dDateStart .. dateOfDeath .. dDateEnd end end local result = infocards.formatDateImpl ( parsedDateOfDeath, 'dday', appendToCategory and 'Умершие' or nil ) if ( calculateAge ) then local age = infocards.age ( parsedDateOfBirth, parsedDateOfDeath ) if ( age and age > 0 ) then result = result .. ' <span class="nowrap">(' .. age .. ' ' .. mw.language.new( 'ru' ):plural( age, 'год', 'года', 'лет') .. ')</span>' end -- returns category to recently deceased persons local unixAvailable, unixDateOfDeath = pcall(function() local r = os.time(parsedDateOfDeath) if ( r ~= os.time() ) then return r end error() end) if (appendToCategory) then if ( unixAvailable and os.time() - unixDateOfDeath < 31536000 ) then result = result .. dateCat.categoryRecentlyDeceased elseif (age and age < 0) then result = result .. dateCat.categoryNegativeAge end end end return result end function infocards.age( parsedBirthDate, parsedFinishDate ) if ( parsedBirthDate == nil or parsedFinishDate == nil ) then return nil end local bd = parsedBirthDate["day"] local bm = parsedBirthDate["month"] local by = parsedBirthDate["year"] local dd = parsedFinishDate["day"] local dm = parsedFinishDate["month"] local dy = parsedFinishDate["year"] if ( bd and bm and by and dd and dm and dy ) then if ( dm > bm or ( dm == bm and dd >= bd ) ) then return dy - by else return dy - by - 1 end else return nil end end function infocards.formatDateImpl( parsedDate, infocardClass, categoryNamePrefix ) local datePart = '<span class="nowrap">' --Temporary hack in order to enable export dates to wikidata if infocardClass == "bday" then datePart = '<span class="no-wikidata" data-wikidata-property-id="P569">' elseif infocardClass == "dday" then datePart = '<span class="no-wikidata" data-wikidata-property-id="P570">' end local t1 = { day = parsedDate.osday, month = parsedDate.osmonth, year = parsedDate.osyear } local t2 = { day = parsedDate.day, month = parsedDate.month, year = parsedDate.year } datePart = datePart .. moduleDates.formatWikiImpl( t1, t2, infocardClass, categoryNamePrefix ) datePart = datePart .. '</span>' return datePart end function infocards.convertToDate( possibleDateString ) possibleDateString = mw.ustring.gsub( possibleDateString, '−', '-') local simpleDate = mw.ustring.match(possibleDateString, '^%s*([%-%d%.]+)%s*$', 0) if ( simpleDate ) then return infocards.convertToDateNewStylePart( simpleDate ) end local complexDate1, complexDate2 = mw.ustring.match(possibleDateString, '^%s*([%-%d%.]+)%s*%(([%-%d%.]+)%)%s*$', 0) if ( complexDate1 and complexDate2) then local table1 = infocards.convertToDateNewStylePart( complexDate1 ) local table2 = infocards.convertToDateOldStylePart( complexDate2 ) if ( table1 and table2 ) then return { year = table1["year"], month = table1["month"], day = table1["day"], osyear = table2["year"], osmonth = table2["month"], osday = table2["day"] } else return nil end end return nil end function infocards.convertToDateNewStylePart( possibleDateString ) local ny = mw.ustring.match(possibleDateString, '^(%-?%d+)$', 0) if (ny ~= nil) then return {year = tonumber(ny)} end return infocards.convertToDateCommonPart( possibleDateString ) end function infocards.convertToDateOldStylePart( possibleDateString ) local nd = mw.ustring.match(possibleDateString, '^(%-?%d+)$', 0) if (nd ~= nil) then return {day = tonumber(nd)} end return infocards.convertToDateCommonPart( possibleDateString ) end function infocards.convertToDateCommonPart( possibleDateString ) local sDay, sMonth, sYear local day, month, year sDay, sMonth, sYear = mw.ustring.match( possibleDateString, '^(%d?%d)%.(%d?%d)%.(%-?%d+)$', 0 ) if sDay ~= nil and sMonth ~= nil and sYear ~= nil then day = tonumber( sDay ) month = tonumber( sMonth ) year = tonumber( sYear ) if day >= 1 and day <= 32 and month >= 1 and month <= 12 then return { day = day, month = month, year = year } end end sDay, sMonth = mw.ustring.match( possibleDateString, '^(%d?%d)%.(%d?%d+)$', 0 ) if sDay ~= nil and sMonth ~= nil then day = tonumber( sDay ) month = tonumber( sMonth ) if day >= 1 and day <= 32 and month >= 1 and month <= 12 then return { day = day, month = month } end end sMonth, sYear = mw.ustring.match( possibleDateString, '^(%d?%d)%.(%-?%d+)$', 0 ) if sMonth ~= nil and sYear ~= nil then month = tonumber( sMonth ) year = tonumber( sYear ) if month >= 1 and month <= 12 then return { month = month, year = year } end end return nil end return infocards 6c1e746d6605d4d101f6aa9fd3e4824b60c64ef7 Шаблон:Число 10 160 362 2023-06-20T10:24:09Z ruwiki>Stjn 0 лучше так тогда для лимитов wikitext text/x-wiki {{formatnum: {{replace|{{{1}}}|,|.}} }}{{#if: {{{1|}}} | {{#if: {{{2|}}} | {{nobr|1=&nbsp;{{{2|}}}}} }} }}<noinclude> {{doc}} </noinclude> acfc1e9cec817e6742b18106f020ac388ececc7e Шаблон:Карточка/оригинал имени 10 268 697 2023-07-04T10:53:34Z ruwiki>Wikisaurus 0 wikitext text/x-wiki {{wikidata|p1559[language!:ru]|{{{1|}}}|before={{{before|}}}|separator=<br>|conjunction=<br>|monolingualLangTemplate={{{monolingualLangTemplate|lang}}}|from={{{from|}}}}}<!-- -->{{#if:{{NAMESPACE}}||{{#if:{{{1|}}}|{{#ifeq:{{#invoke:String|find|{{{1|}}}|span}}|0|[[Категория:Википедия:Статьи с оригиналом имени без шаблона lang-XX]]}}}}}}<noinclude>{{doc}}</noinclude> a294e3f7f61c5206ca5671b72e21804d7a32fcbc Шаблон:Карточка/оригинал названия 10 154 350 2023-07-04T10:53:52Z ruwiki>Wikisaurus 0 wikitext text/x-wiki {{wikidata|p1705[language!:ru]|{{{1|}}}|separator=<br>|conjunction=<br>|monolingualLangTemplate=lang|from={{{from|}}}}}<!-- -->{{#if:{{NAMESPACE}}||{{#if:{{{1|}}}|{{#ifeq:{{#invoke:String|find|{{{1|}}}|span}}|0|[[Категория:Википедия:Статьи с оригиналом названия без шаблона lang-XX]]}}}}}}<noinclude>{{doc}}</noinclude> 4eccda042428e1113ff320ff5d6b760a7f52b088 Шаблон:Государство 10 122 286 2023-07-18T14:45:13Z ruwiki>Krestenti 0 wikitext text/x-wiki {{Карточка |имя = Государство |автозаголовки = да |from = {{{from|}}} |вверху0 = {{#switch: {{{Статус|}}} | виртуальное = [[Виртуальное государство]] | особый = {{#if: {{{Спорный статус|}}} | {{{Особый спорный статус|}}} }} | Непризнанное | непризнанное = {{#if: {{{Спорный статус|}}} | [[Непризнанные и частично признанные государства|Непризнанное государство]] }} | Частично признанное | частично признанное = {{#if: {{{Спорный статус|}}} | [[Непризнанные и частично признанные государства|Частично признанное государство]] }} }} |вверху = {{карточка/название|{{{Русское название|}}}|from={{{from|}}}}} |вверху2 = {{карточка/оригинал названия|{{карточка/официальное название|{{{Оригинальное название|}}}|from={{{from|}}}}}|from={{{from|}}}}} |изображение = {{Карточка/флаг и герб | флаг = {{{Флаг|}}} | флаг ширина = {{{Размер флага|}}}{{{размер флага|}}} | флаг подпись = [[{{#if: {{{Ссылка на флаг|}}} | {{{Ссылка на флаг}}} | Флаг {{{Родительный падеж}}} }}|Флаг]] | герб = {{{Герб|}}} | герб ширина = {{{Размер герба|}}}{{{размер герба|}}} | герб подпись = {{#if: {{{Отображаемая подпись герба|}}} | {{{Отображаемая подпись герба}}} | {{#if: {{{Вместо герба|}}} | [[{{{Вместо герба}}} {{{Родительный падеж}}}|{{{Вместо герба}}}]] | [[Герб {{{Родительный падеж}}}|Герб]] }} }} |from={{{from|}}}}} |текст1 = {{br separated entries | {{#if: {{{Девиз|}}} | [[Девиз]]: ''«{{{Девиз}}}»'' }} | {{#if: {{{Перевод девиза|}}} | ''«{{{Перевод девиза}}}»'' }} }} |текст2 = {{#if: {{{Без гимна|}}} || {{#if: {{{Название гимна|}}} | {{br separated entries | [[Государственный гимн|Гимн]]: [[Гимн {{{Родительный падеж}}}|''«{{{Название гимна}}}»'']] | {{#if: {{{Перевод названия гимна|}}} | ''«{{{Перевод названия гимна}}}»'' }} }} | [[Гимн {{{Родительный падеж<noinclude>|</noinclude>}}}|Государственный гимн {{{Родительный падеж<noinclude>|</noinclude>}}}]] }}{{#if: {{{Аудио|}}} | {{#if: {{{Аудио|}}} | [[Файл:{{{Аудио|}}}|center]] }} }} }} |текст3 = {{#if: {{wikidata|p242|{{{На карте|}}}|plain=true|from={{{from|}}}}} | {{wikidata|p242|{{{На карте|}}}|size={{#if: {{{Размер карты|}}}{{{размер карты|}}} | {{{Размер карты|}}}{{{размер карты|}}} | 300x300px }}|caption={{{Подпись к карте|}}}{{{подпись к карте|}}}|from={{{from|}}}}}<!-- -->{{#if: {{{На карте2|}}} | <br>[[Файл:{{{На карте2}}}|{{{Размер карты2|{{{размер карты2|300x300px}}}}}}]]{{#if:{{{Подпись к карте 2|}}}{{{подпись к карте 2|}}}|<br>{{{Подпись к карте 2|{{{подпись к карте 2|}}}}}} }} }} }} |заголовок4 = {{#if: {{{sovereignty_type|}}} | {{{sovereignty_type}}} | [[История {{{Родительный падеж}}}|История]] }} |стиль_заголовка4 = padding-bottom:0; border-bottom:0; text-align:left; |блок5 = {{Карточка/блок с маркерами |метка1 = {{nobr|{{{Дата1}}}}} |текст1 = {{{Этап1|}}} |метка2 = {{nobr|{{{Дата2}}}}} |текст2 = {{{Этап2|}}} |метка3 = {{nobr|{{{Дата3}}}}} |текст3 = {{{Этап3|}}} |метка4 = {{nobr|{{{Дата4}}}}} |текст4 = {{{Этап4|}}} |метка5 = {{nobr|{{{Дата5}}}}} |текст5 = {{{Этап5|}}} |метка6 = {{nobr|{{{Дата6}}}}} |текст6 = {{{Этап6|}}} |метка7 = {{nobr|{{{Дата7}}}}} |текст7 = {{{Этап7|}}} |метка8 = {{nobr|{{{Дата8}}}}} |текст8 = {{{Этап8|}}} |метка9 = {{nobr|{{{Дата9}}}}} |текст9 = {{{Этап9|}}} |метка10 = {{nobr|{{{Дата10}}}}} |текст10 = {{{Этап10|}}} |метка11 = {{nobr|{{{Дата11}}}}} |текст11 = {{{Этап11|}}} |метка12 = {{nobr|{{{Дата12}}}}} |текст12 = {{{Этап12|}}} |from={{{from|}}}}} |заголовок6 = - |метка7 = [[Основание государства|{{#if: {{{Основана|}}} | Основана | Основано }}]] |текст7 = {{{Основана|}}}{{{Основано|}}} |викиданные7 = <!-- СПОРНЫЙ СТАТУС --> <!-- Спорный статус заполнен --> |метка8 = [[Основание государства|Дата образования]] |текст8 = {{#if: {{{Спорный статус|}}} | {{{Дата образования|}}} }} |викиданные8 = |метка9 = Провозглашение независимости |текст9 = {{#if: {{{Спорный статус|}}} | {{#if: {{{Провозглашение независимости|}}} | {{{Провозглашение независимости}}} {{#if: {{{Независимость от|}}} | (от&nbsp;{{{Независимость от}}}) }} }} }} |викиданные9 = |метка10 = [[Международно-правовое признание|Дипломатическое признание]] |текст10 = {{#if: {{{Спорный статус|}}} | {{{Дипломатическое признание|}}} }} |викиданные10 = <!-- Спорный статус не заполнен --> |метка11 = {{#if: {{{Отображаемый тип независимости|}}} | {{{Отображаемый тип независимости}}} | [[Суверенитет|{{#if: {{{Даты независимости|}}} | Даты | Дата }} независимости]] }} |текст11 = {{#if: {{{Спорный статус|}}} || {{#if: {{{Дата независимости|}}}{{{Даты независимости|}}} | {{{Дата независимости|{{{Даты независимости|}}}}}} {{#if: {{{Независимость от|}}} | (от&nbsp;{{{Независимость от}}}) }} }} }} |викиданные11 = <!-- / СПОРНЫЙ СТАТУС --> |метка12 = [[Официальный язык|{{#if: {{{Язык|}}} | Официальный язык | Официальные языки }}]] |текст12 = {{{Язык|{{{Языки|}}}}}} |викиданные12 = p37 |метка13 = [[Столица]] |текст13 = {{{Столица|}}} |викиданные13 = p36 |метка14 = {{#if: {{{Крупнейший город|}}} | Крупнейший город | Крупнейшие города }} |текст14 = {{{Крупнейший город|}}}{{{Крупнейшие города|}}} |викиданные14 = |метка15 = [[Форма государственного правления|Форма правления]] |текст15 = {{{Форма правления|}}} |викиданные15 = |метка16 = [[Форма государственного устройства|Государственный строй]] |текст16 = {{{Государственный строй|}}} |метка17 = {{{Должность руководителя 1|{{{Должности руководителей}}}}}} |текст17 = {{{Руководитель 1|{{{Руководители|}}}}}} |метка18 = {{{Должность руководителя 2}}} |текст18 = {{{Руководитель 2|}}} |метка19 = {{{Должность руководителя 3}}} |текст19 = {{{Руководитель 3|}}} |метка20 = {{{Должность руководителя 4}}} |текст20 = {{{Руководитель 4|}}} |метка21 = {{{Должность руководителя 5}}} |текст21 = {{{Руководитель 5|}}} |метка22 = {{{Должность руководителя 6}}} |текст22 = {{{Руководитель 6|}}} |метка23 = [[Государственная религия|Гос. религия]] |текст23 = {{{Государственная религия|}}} |викиданные23 = |блок24 = {{Карточка/блок с маркерами |подзаголовок = [[Территория государства|Территория]] |метка1 = Всего |текст1 = {{br separated entries | {{число|{{{Территория|}}}|км²}}{{#if: {{{Место по территории|}}} | &nbsp;{{nobr|([[Список государств и зависимых территорий по площади|{{{Место по территории}}}-я в мире]])}} }} | {{число|{{{Территория2|}}}|км²}} }} |метка2 = % водной поверхности |текст2 = {{#ifeq: {{{Процент воды|}}} | - || {{{Процент воды|}}} }} |from={{{from|}}}}} |блок25 = {{Карточка/блок с маркерами |подзаголовок = [[{{Население государства|{{PAGENAME}}}}]] |метка1 = Оценка {{#if: {{{Год оценки|}}} | ({{{Год оценки}}}) }} |текст1 = {{br separated entries | {{число|{{{Население|}}}|чел.}}{{#if: {{{Место по населению|}}} | &nbsp;([[Список стран по населению|{{{Место по населению}}}-е]]) }} | {{число|{{{Население2|}}}|чел.}} }} |метка2 = Перепись {{#if: {{{Год переписи|}}} | ({{{Год переписи}}}) }} |текст2 = {{число|{{{Население по переписи|}}}|чел.}} |метка3 = [[Плотность населения|Плотность]] |текст3 = {{число|{{{Плотность населения|}}}|чел./км²}}{{#if: {{{Место по плотности|}}} | &nbsp;([[Список стран по плотности населения|{{{Место по плотности}}}-я]]) }} |from={{{from|}}}}} |блок26 = {{Карточка/блок с маркерами |подзаголовок = [[Валовой внутренний продукт|ВВП]] |метка1 = Итого {{#if: {{{Год расчёта ВВП|}}} | ({{{Год расчёта ВВП}}}) }} |текст1 = {{число|{{{ВВП|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП|}}} | &nbsp;([[Список стран по ВВП (ППС)|{{{Место по ВВП}}}-й]]) }} |метка2 = На душу населения |текст2 = {{число|{{{ВВП на душу населения|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП на душу населения|}}} | &nbsp;([[Список стран по ВВП (ППС) на душу населения|{{{Место по ВВП на душу населения}}}-й]]) }} |from={{{from|}}}}} |блок27 = {{Карточка/блок с маркерами |подзаголовок = [[Валовой внутренний продукт|ВВП]] <span style="font-weight:normal;">([[Паритет покупательной способности|ППС]])</span> |метка1 = Итого {{#if: {{{Год расчёта ВВП (ППС)|}}} | ({{{Год расчёта ВВП (ППС)}}}) }} |текст1 = {{число|{{{ВВП (ППС)|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП (ППС)|}}} | &nbsp;([[Список стран по ВВП (ППС)|{{{Место по ВВП (ППС)}}}-й]]) }} |метка2 = На душу населения |текст2 = {{число|{{{ВВП (ППС) на душу населения|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП (ППС) на душу населения|}}} | &nbsp;([[Список стран по ВВП (ППС) на душу населения|{{{Место по ВВП (ППС) на душу населения}}}-й]]) }} |from={{{from|}}}}} |блок28 = {{Карточка/блок с маркерами |подзаголовок = [[Валовой внутренний продукт|ВВП]] <span style="font-weight:normal;">(номинал)</span> |метка1 = Итого {{#if: {{{Год расчёта ВВП (номинал)|}}} | ({{{Год расчёта ВВП (номинал)}}}) }} |текст1 = {{число|{{{ВВП (номинал)|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП (номинал)|}}} | &nbsp;([[Список стран по ВВП (номинал)|{{{Место по ВВП (номинал)}}}-й]]) }} |метка2 = На душу населения |текст2 = {{число|{{{ВВП (номинал) на душу населения|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП (номинал) на душу населения|}}} | &nbsp;([[Список стран по ВВП (номинал) на душу населения|{{{Место по ВВП (номинал) на душу населения}}}-й]]) }} |from={{{from|}}}}} |метка29 = [[Индекс человеческого развития|ИЧР]] {{#if: {{{Год расчёта ИРЧП|}}} | <span style="font-weight:normal;">({{{Год расчёта ИРЧП}}})</span> }} |текст29 = {{{ИРЧП|}}}{{#if: {{{Уровень ИРЧП|}}} | &nbsp;({{{Уровень ИРЧП}}}{{#if: {{{Место по ИРЧП|}}} | &#059; [[Список стран по индексу человеческого развития|{{{Место по ИРЧП}}}-е&nbsp;место]] }}) }} |викиданные29 = |метка30 = [[Названия жителей]] |текст30 = {{{Этнохороним|}}} |викиданные30 = |метка31 = [[Валюта]] |текст31 = {{{Валюта|}}} |викиданные31 = P38 |метка32 = [[Домен верхнего уровня|{{wikidata number switch|P78|{{{Домен|}}}|{{{Домены|}}}|Интернет-домен|Интернет-домены}}]] |текст32 = {{{Домен|}}}{{{Домены|}}} |викиданные32 = P78 |метка33 = [[ISO 3166-1|Код ISO]] |текст33 = |викиданные33 = P297 |метка34 = [[Список кодов МОК|Код МОК]] |текст34 = |викиданные34 = P984 |метка35 = [[Список телефонных кодов стран|Телефонный код]] |текст35 = {{#if: {{{Телефонный код|}}} | {{#ifeq: {{{Телефонный код|}}} | - | - | +{{{Телефонный код}}} }} }} |викиданные35 = P474 |метка36 = [[Часовой пояс|{{wikidata number switch|P421|{{{Часовой пояс|}}}|{{{Часовые пояса|}}}|Часовой пояс|Часовые пояса}}]] |текст36 = {{{Часовой пояс|}}}{{{Часовые пояса|}}} |викиданные36 = P421 |метка37 = Автомобильное движение |текст37 = {{{Автомобильное движение|}}} |викиданные37 = P1622 |текст38 = {{{Примечания|}}} |стиль_текста38 = border-top:1px solid #a2a9b1; color:#54595d; padding-top:0.5em; text-align:left; |внизу = {{карточка/Викисклад|from={{{from|}}}}} }}{{#if: {{{nocat|}}}{{NAMESPACE}} || <!-- -->{{#if: {{{lat_deg|}}} | {{coord|1={{{lat_deg|}}}|2={{{lat_min|0}}}|3={{{lat_sec|0}}}|4={{#if: {{{lat_dir|}}} | {{{lat_dir}}} | N }}|5={{{lon_deg|}}}|6={{{lon_min|0}}}|7={{{lon_sec|0}}}|8={{#if: {{{lon_dir|}}} | {{{lon_dir}}} | E }}|type=country|region={{{region|}}}|scale={{{CoordScale|}}}|format=dms|display=title}} | {{#if: {{#property: p625}} | {{wikidata|p625|type=country|region={{{region|}}}|scale={{{CoordScale|}}}|from={{{from|}}}}} | [[Категория:Государства без указанных географических координат]] }} }}<!-- -->{{#switch: {{{Статус|}}} | Виртуальное | виртуальное = [[Категория:Виртуальные государства]] | Непризнанное | непризнанное = [[Категория:Непризнанные государства]] | Частично признанное | частично признанное = [[Категория:Частично признанные государства]] | особый = {{#if: {{{Спорный статус|}}} | {{#if: {{{Особая категория|}}}|[[Категория:{{{Особая категория|}}}]]|[[Категория:Государства по алфавиту]]}} }} | [[Категория:Государства по алфавиту]] }}<!-- -->{{Государство/Викиданные}} }}<noinclude>{{doc}}</noinclude> d5532838af5967020fc4f653452458ba05aea4cf Шаблон:Государство/doc 10 184 410 2023-10-11T16:26:29Z ruwiki>CyberNik01 0 wikitext text/x-wiki {{docpage}} Этот [[Википедия:Шаблоны-карточки|шаблон-карточка]] используется для вставки карточки в статьи о современных государствах; * для исторических государств используйте {{t|историческое государство}}. * для составных частей государств используйте {{t|Административная единица}}. == Образец для копирования == <pre> {{Государство |Статус = <!-- виртуальное / непризнанное / частично признанное / регион; для признанных государств не заполнять --> |Русское название = |Оригинальное название = |Родительный падеж = |Герб = |Вместо герба = |Девиз = {{lang-??2|}}<!-- на оф. языке / языках гос-ва --> |Перевод девиза = |Название гимна = |Перевод названия гимна = |Аудио = |Форма правления = |Государственный строй = |Государственная религия = |На карте = |подпись к карте = |На карте2 = |Язык/Языки = |Основано/Основана = |Дата/Даты независимости = |Независимость от = |Столица = |Крупнейшие города = |Должность руководителя 1 = |Руководитель 1 = |Должность руководителя 2 = |Руководитель 2 = |Должность руководителя 3 = |Руководитель 3 = |Должность руководителя 4 = |Руководитель 4 = |Должность руководителя 5 = |Руководитель 5 = |Место по территории = |Территория = |Процент воды = |Этнохороним = |Место по населению = |Население = |Год оценки = |Население по переписи = |Год переписи = |Плотность населения = |Место по плотности = |ВВП (ППС) = |Год расчёта ВВП (ППС) = |Место по ВВП (ППС) = |ВВП (ППС) на душу населения = |Место по ВВП (ППС) на душу населения = |ВВП (номинал) = |Год расчёта ВВП (номинал) = |Место по ВВП (номинал) = |ВВП (номинал) на душу населения = |Место по ВВП (номинал) на душу населения = |ИРЧП = |Год расчёта ИРЧП = |Место по ИРЧП = |Уровень ИРЧП = |Валюта = |Домен/Домены = |Телефонный код = |Часовой пояс = |Автомобильное движение = |Примечания = <!-- |Без флага и герба=* --> <!-- |Без гимна=* --> }} </pre> == Описание параметров == Некоторые параметры могут быть заданы в разных формах (например, в единственном либо множественном числе). После копирования образца в статью заполните только строку с более подходящей формой. Например, в статье [[Албания]]&nbsp;— <pre> |Язык = [[Албанский язык|албанский]]</pre> а в статье [[Канада]]&nbsp;— <pre> |Языки = [[Английский язык|английский]] и [[Французский язык|французский]]</pre> Для статей о регионах с нечётким правовым статусом используйте параметр <code>Спорный статус = да</code> и параметры «Основано», «Дата образования», «Провозглашение независимости» и «Дипломатическое признание» вместо «Дата независимости» и «Основано»: <pre> |Спорный статус = да |Основано = |Основана = |Дата образования = |Провозглашение независимости = |Дипломатическое признание = |Независимость от = </pre> Для статей о [[Непризнанные и частично признанные государства|непризнанных государствах]] или [[Автономный регион|автономных регионах]], не являющихся самостоятельными государствами, используйте параметр <code>Статус&nbsp;=&nbsp;непризнанное</code> или <code>Статус = регион</code>, это отключит автоматическое добавление категории [[:Категория:Государства по алфавиту|Государства по алфавиту]], а в первом случае также добавит категорию [[:Категория:Непризнанные государства|Непризнанные государства]]. Для статей о [[Виртуальное государство|виртуальных государствах]] используйте параметр <code>Статус = виртуальное</code>, это добавит категорию [[:Категория:Виртуальные государства|Виртуальные государства]]. == Пример использования == {{demo|reverse=1|br=|<nowiki>{{Государство |Русское название = Финляндская Республика |Оригинальное название = {{lang-fi|Suomen Tasavalta}}<br>{{lang-sv|Republiken Finland}} |Родительный падеж = Финляндии |Герб = Coat of arms of Finland.svg |Флаг = Flag of Finland.svg<!-- иначе используется конструкция {{флаг|{{FULLPAGENAME}}|размер=135px}} --> |Вместо герба = |Девиз = |Перевод девиза = |Название гимна = Maamme |Перевод названия гимна = Наш край |Аудио = |Форма правления = [[президентская республика]] |Государственный строй = [[унитарное государство]] |Государственная религия = |На карте = EU-Finland.svg |подпись к карте = Расположение '''Финляндии''' (тёмно-зелёный):<br>— в [[Европа|Европе]] (светло-зелёный и тёмно-серый)<br>— в [[Европейский союз|Европейском союзе]] (светло-зелёный) |На карте2 = |Языки = [[финский язык|финский]], [[шведский язык|шведский]] |Основано/Основана = |Дата независимости = [[6 декабря]] [[1917]] |Независимость от = [[Россия|России]] |Столица = [[Хельсинки]] |Крупнейший город = Хельсинки |Должность руководителя 1 = [[Президент Финляндии|Президент]] |Руководитель 1 = [[Халонен, Тарья Каарина|Тарья Халонен]] |Должность руководителя 2 = [[Премьер-министр Финляндии|Премьер-министр]] |Руководитель 2 = [[Ванханен, Матти Танели|Матти Ванханен]] |Место по территории = 63 |Территория = 338 145 |Процент воды = 9,96 |Этнохороним = финляндец, финляндка |Место по населению = 106 |Население = 5 219 732 |Год оценки = 2003 |Население по переписи = |Год переписи = |Плотность населения = 15,4 |Место по плотности = |ВВП = |Год расчёта ВВП = |Место по ВВП = |ВВП на душу населения = |Место по ВВП на душу населения = |ИРЧП = |Год расчёта ИРЧП = |Место по ИРЧП = |Уровень ИРЧП = |Валюта = [[евро]]<ref name="money">до 2002 — [[финская марка]]</ref> |Домены = [[.fi]], [[.ax]] (для [[Аландские острова|Аландских островов]]) |Телефонный код = 358 |Часовой пояс = +2 |Автомобильное движение = |Примечания = <references/> }}</nowiki>}} == TemplateData == <templatedata> { "params": { "Спорный статус": {}, "Статус": {}, "Русское название": {}, "Оригинальное название": {}, "Флаг": { "type": "wiki-file-name" }, "Ссылка на флаг": {}, "Родительный падеж": {}, "Герб": { "type": "wiki-file-name" }, "Отображаемая подпись герба": {}, "Вместо герба": {}, "Девиз": {}, "Перевод девиза": {}, "Без гимна": {}, "Название гимна": {}, "Перевод названия гимна": {}, "Аудио": {}, "На карте": {}, "На карте2": {}, "Дата1": {}, "Дата2": {}, "Дата3": {}, "Дата4": {}, "Дата5": {}, "Дата6": {}, "Дата7": {}, "Дата8": {}, "Дата9": {}, "Дата10": {}, "Дата11": {}, "Дата12": {}, "sovereignty_type": {}, "Этап1": {}, "Этап2": {}, "Этап3": {}, "Этап4": {}, "Этап5": {}, "Этап6": {}, "Этап7": {}, "Этап8": {}, "Этап9": {}, "Этап10": {}, "Этап11": {}, "Этап12": {}, "Основана": {}, "Основано": {}, "Дата образования": {}, "Провозглашение независимости": {}, "Независимость от": {}, "Дипломатическое признание": {}, "Отображаемый тип независимости": {}, "Даты независимости": {}, "Дата независимости": {}, "Язык": {}, "Языки": {}, "Столица": {}, "Крупнейший город": {}, "Крупнейшие города": {}, "Форма правления": {}, "Должность руководителя 1": {}, "Должности руководителей": {}, "Руководитель 1": {}, "Руководители": {}, "Должность руководителя 2": {}, "Руководитель 2": {}, "Должность руководителя 3": {}, "Руководитель 3": {}, "Должность руководителя 4": {}, "Руководитель 4": {}, "Должность руководителя 5": {}, "Руководитель 5": {}, "Государственная религия": {}, "Место по территории": {}, "Территория": {}, "Процент воды": {}, "Территория2": {}, "Население": {}, "Год оценки": {}, "Год переписи": {}, "Население2": {}, "Место по населению": {}, "Население по переписи": {}, "Плотность населения": {}, "Место по плотности": {}, "ВВП": {}, "Год расчёта ВВП": {}, "Место по ВВП": {}, "ВВП на душу населения": {}, "Место по ВВП на душу населения": {}, "ВВП (ППС)": {}, "Год расчёта ВВП (ППС)": {}, "Место по ВВП (ППС)": {}, "ВВП (ППС) на душу населения": {}, "Место по ВВП (ППС) на душу населения": {}, "ВВП (номинал)": {}, "Год расчёта ВВП (номинал)": {}, "Место по ВВП (номинал)": {}, "ВВП (номинал) на душу населения": {}, "Место по ВВП (номинал) на душу населения": {}, "Год расчёта ИРЧП": {}, "ИРЧП": {}, "Уровень ИРЧП": {}, "Место по ИРЧП": {}, "Этнохороним": {}, "Валюта": {}, "Домены": {}, "Домен": {}, "Телефонный код": {}, "Часовые пояса": {}, "Часовой пояс": {}, "Примечания": {}, "nocat": { "type": "boolean" }, "lat_deg": {}, "lat_min": {}, "lat_sec": {}, "lat_dir": {}, "lon_deg": {}, "lon_min": {}, "lon_sec": {}, "lon_dir": {}, "region": {}, "CoordScale": {}, "Размер герба": { "aliases": [ "размер герба" ], "type": "number" }, "Размер флага": { "aliases": [ "размер флага" ], "type": "number" }, "Размер карты": { "aliases": [ "размер карты" ] }, "Подпись к карте": { "aliases": [ "подпись к карте" ] }, "Размер карты2": { "aliases": [ "размер карты2" ] }, "Государственный строй": {}, "Автомобильное движение": {} }, "paramOrder": [ "Статус", "Спорный статус", "Русское название", "Оригинальное название", "Флаг", "Размер флага", "Ссылка на флаг", "Родительный падеж", "Герб", "Размер герба", "Отображаемая подпись герба", "Вместо герба", "Девиз", "Перевод девиза", "Без гимна", "Название гимна", "Перевод названия гимна", "Аудио", "На карте", "Размер карты", "Подпись к карте", "На карте2", "Размер карты2", "Дата1", "Дата2", "Дата3", "Дата4", "Дата5", "Дата6", "Дата7", "Дата8", "Дата9", "Дата10", "Дата11", "Дата12", "sovereignty_type", "Этап1", "Этап2", "Этап3", "Этап4", "Этап5", "Этап6", "Этап7", "Этап8", "Этап9", "Этап10", "Этап11", "Этап12", "Основана", "Основано", "Дата образования", "Провозглашение независимости", "Независимость от", "Дипломатическое признание", "Отображаемый тип независимости", "Даты независимости", "Дата независимости", "Язык", "Языки", "Столица", "Крупнейший город", "Крупнейшие города", "Форма правления", "Государственный строй", "Должность руководителя 1", "Должности руководителей", "Руководитель 1", "Руководители", "Должность руководителя 2", "Руководитель 2", "Должность руководителя 3", "Руководитель 3", "Должность руководителя 4", "Руководитель 4", "Должность руководителя 5", "Руководитель 5", "Государственная религия", "Место по территории", "Территория", "Процент воды", "Территория2", "Население", "Год оценки", "Год переписи", "Население2", "Место по населению", "Население по переписи", "Плотность населения", "Место по плотности", "ВВП", "Год расчёта ВВП", "Место по ВВП", "ВВП на душу населения", "Место по ВВП на душу населения", "ВВП (ППС)", "Год расчёта ВВП (ППС)", "Место по ВВП (ППС)", "ВВП (ППС) на душу населения", "Место по ВВП (ППС) на душу населения", "ВВП (номинал)", "Год расчёта ВВП (номинал)", "Место по ВВП (номинал)", "ВВП (номинал) на душу населения", "Место по ВВП (номинал) на душу населения", "Год расчёта ИРЧП", "ИРЧП", "Уровень ИРЧП", "Место по ИРЧП", "Этнохороним", "Валюта", "Домены", "Домен", "Телефонный код", "Часовые пояса", "Часовой пояс", "Автомобильное движение", "Примечания", "lat_deg", "lat_min", "lat_sec", "lat_dir", "lon_deg", "lon_min", "lon_sec", "lon_dir", "region", "CoordScale", "nocat" ], "format": "block" } </templatedata> == См. также == * {{tl|Историческое государство}} <includeonly> [[Категория:Шаблоны-карточки:Географические объекты]] </includeonly> b1e2b1107db0671d3bcc4dda5bd29020192c442e Шаблон:Сначала имя 10 275 711 2023-11-15T18:34:52Z ruwiki>Stjn 0 читаемость wikitext text/x-wiki {{safesubst:<noinclude />#ifexpr: {{safesubst:<noinclude />str find|{{safesubst:<noinclude />До символа|{{{1}}}|(}}|,}} = -1 <!-- -->|{{safesubst:<noinclude />До символа|{{{1}}}|(}}<!-- -->|{{safesubst:<noinclude />trim|{{safesubst:<noinclude />После символа|{{safesubst:<noinclude />До символа|{{{1}}}|(}}|,}}}} {{safesubst:<noinclude />До символа|{{safesubst:<noinclude />До символа|{{{1}}}|(}}|,}}<!-- -->}}<noinclude> {{doc}} </noinclude> c3a2e3e13dba0ae595a7c147ca692be2eb183f38 Шаблон:Скрытый блок 10 200 446 2023-12-21T00:36:59Z ruwiki>Stjn 0 неактуальный параметр wikitext text/x-wiki {{Начало скрытого блока |id = {{{id|}}} |тип = {{{тип|{{{type|}}}}}} |состояние = {{{state|{{{состояние|collapsed}}}}}} |класс_тела = {{{класс_тела|{{{класс тела|}}}}}} |стиль_тела = {{{frame-style|{{{стиль_тела|{{{стиль тела|}}}}}}}}} |рамка = {{{Рамка|{{{border|{{{рамка|}}}}}}}}} |заголовок = {{{Заголовок|{{{заголовок|{{{Заглавие|{{{заглавие|{{{Название|{{{название|{{{header|{{{title|{{{1}}}}}}}}}}}}}}}}}}}}}}}}}}} |ссылка = {{{Ссылка|{{{ссылка|}}}}}} |класс_заголовка = {{{класс_заголовка|{{{класс заголовка|}}}}}} |шрифт_заголовка = {{{Шрифт_заголовка|{{{шрифт_заголовка|{{{шрифт заголовка|}}}}}}}}} |наклон_заголовка = {{{Наклон_заголовка|{{{наклон_заголовка|{{{наклон заголовка|}}}}}}}}} |фон_заголовка = {{{Фон_заголовка|{{{bg1|{{{фон_заголовка|{{{фон заголовка|}}}}}}}}}}}} |выравнивание_заголовка = {{{Выравнивание_заголовка|{{{ta1|{{{выравнивание_заголовка|{{{выравнивание заголовка|}}}}}}}}}}}} |стиль_заголовка = {{{title-style|{{{Стиль_заголовка|{{{extra1|{{{стиль_заголовка|{{{стиль заголовка|}}}}}}}}}}}}}}} |класс_текста = {{{класс_текста|{{{класс текста|}}}}}} |шрифт_текста = {{{Шрифт_текста|{{{шрифт_текста|{{{шрифт текста|}}}}}}}}} |наклон_текста = {{{Наклон_текста|{{{наклон_текста|{{{наклон текста|}}}}}}}}} |фон_текста = {{{Фон_текста|{{{bg2|{{{фон_текста|{{{фон текста|}}}}}}}}}}}} |выравнивание_текста = {{{Выравнивание_текста|{{{ta2|{{{выравнивание_текста|{{{выравнивание текста|}}}}}}}}}}}} |стиль_текста = {{{content-style|{{{Стиль_текста|{{{extra2|{{{стиль_текста|{{{стиль текста|}}}}}}}}}}}}}}}}} {{{content|{{{Содержание|{{{содержание|{{{2}}}}}}}}}}}} {{#if: {{{footer|}}} | <div style="{{{footer-style|{{{title-style|}}}}}}">{{{footer}}}</div> }} {{Конец скрытого блока}}<noinclude> {{doc}} </noinclude> 792dc9fb2eb659877e2e758f4ce405e1d3f8352b Шаблон:Карточка/изображение/doc 10 222 492 2023-12-26T21:37:39Z ruwiki>Q-bit array 0 [[ВП:Откат|откат]] правок [[Special:Contribs/178.67.199.169|178.67.199.169]] ([[UT:178.67.199.169|обс.]]) к версии DmitTrix wikitext text/x-wiki {{docpage}} {{high-use}} Используется в [[Википедия:Шаблоны-карточки|шаблонах-карточках]] для вывода полей изображений, которые не нужно привязывать к Викиданным (в противном случае используется <code>{{tp|wikidata|P18|caption=<nowiki>{{{описание изображения|}}}</nowiki>|size=<nowiki>{{{ширина|}}}</nowiki>}}</code>). == Заполнение в статьях == Для изображений в формате «'''<nowiki>[[Файл:<Имя>|…]]</nowiki>'''» (и вообще для любого параметра, начинающегося с «'''['''», «'''{'''» или «'''<'''») текст вставится без изменения: <nowiki>{{{изображение|}}}</nowiki> Если же просто указано название изображения, то оно оформится так: <nowiki>[[Файл:{{{изображение|}}}|274x400px]]</nowiki> == Использование шаблона == Вставляется в шаблон {{t|карточка}} — либо в поле {{para|изображение}}, либо в поле {{para|текстN}} (в таком случае может понадобиться сбросить паддинги: {{para|стиль_текстаN|padding:0;}}). Формат применения: <nowiki>| изображение = {{Карточка/изображение|{{{изображение|}}}|size={{{ширина|}}}|caption={{{описание изображения|}}}}}</nowiki> == TemplateData == <templatedata> { "description": "Этот шаблон используется для вставки параметра изображения.", "params": { "1": { "label": "1", "description": "Изображение в любом виде, если '''none''' или '''нет''', то игнорируется.", "type": "string", "required": false }, "caption": { "label": "caption", "description": "Подпись под изображением.", "type": "string", "required": false }, "size": { "aliases": [ "2" ], "label": "size", "description": "Его размер, можно с '''px''' или без, по-умолчанию — '''274x400px'''.", "type": "string" } }, "paramOrder": [ "1", "size", "caption" ] } </templatedata> == См. также == * [[Шаблон:Карточка/изображение/тесты]] (для проверки изменений) * {{tl|URL}} {{Подстраницы шаблона Карточка}} <includeonly> [[Категория:Шаблоны:Подстраницы шаблона Карточка|изображение]] </includeonly> 1a53aa3106ad42492ac93048c8554950e40a1bf8 Шаблон:Учёное звание 10 295 751 2024-01-09T17:19:56Z ruwiki>MBH 0 wikitext text/x-wiki <includeonly>{{#switch: {{{1|}}} <!-- современная Россия --> | РАН = {{#switch: {{{2|}}}| 1 = [[Члены-корреспонденты РАН|член-корреспондент РАН]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты РАН]]}}| 0 = [[Действительные члены РАН|академик РАН]]{{#if:{{NAMESPACE}}||[[Категория:Действительные члены РАН]]}}|<!--пустое значение-->}} <!-- Российская академия наук --> | РАМН = {{#switch: {{{2|}}}| 1 = [[Члены-корреспонденты РАМН|член-корреспондент РАМН]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты РАМН]]}}| 0 = [[Российская академия медицинских наук|академик РАМН]]{{#if:{{NAMESPACE}}||[[Категория:Академики РАМН]]}}|<!--пустое значение-->}} <!-- Российская академия медицинских наук --> | РАО = {{#switch: {{{2|}}}| 1 = [[Российская академия образования|член-корреспондент РАО]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты РАО]]}}| 0 = [[Действительные члены (академики) Российской академии образования|академик РАО]]{{#if:{{NAMESPACE}}||[[Категория:Академики РАО]]}}|<!--пустое значение-->}} <!-- Российская академия образования --> | РАСХН = {{#switch: {{{2|}}}| 1 = [[Российская академия сельскохозяйственных наук|член-корреспондент РАСХН]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты РАСХН]]}}| 0 = [[Российская академия сельскохозяйственных наук|академик РАСХН]]{{#if:{{NAMESPACE}}||[[Категория:Академики РАСХН]]}}|<!--пустое значение-->}} <!-- Российская академия сельскохозяйственных наук --> | РААСН = {{#switch: {{{2|}}}| 1 = [[Члены-корреспонденты Российской академии архитектуры и строительных наук|член-корреспондент РААСН]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты РААСН]]}}| 0 = [[Академики Российской академии архитектуры и строительных наук|академик РААСН]]{{#if:{{NAMESPACE}}||[[Категория:Академики РААСН]]}}|<!--пустое значение-->}} <!-- Российская академия архитектуры и строительных наук --> | РАХ = {{#switch: {{{2|}}}| 1 = [[Российская академия художеств|член-корреспондент РАХ]]<br />{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты РАХ]]}}| 0 = [[Список действительных членов РАХ|академик РАХ]] {{#if:{{NAMESPACE}}||[[Категория:Действительные члены РАХ]]}}|<!--пустое значение-->}} <!-- Российская академия художеств --> <!-- СССР --> | АН СССР = {{#switch: {{{2|}}}| 1 = [[Члены-корреспонденты РАН за всю историю существования|член-корреспондент АН СССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН СССР]]}}| 0 = [[Академики АН СССР|академик АН СССР]]{{#if:{{NAMESPACE}}||[[Категория:Действительные члены АН СССР]]}}|<!--пустое значение-->}} <!-- Академия наук СССР --> | АМН СССР = {{#switch: {{{2|}}}| 1 = [[Академия медицинских наук СССР|член-корреспондент АМН СССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АМН СССР]]}}| 0 = [[Академия медицинских наук СССР|академик АМН СССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики АМН СССР]]}}|<!--пустое значение-->}} <!-- Академия медицинских наук СССР (1944—1992) --> | АПН СССР = {{#switch: {{{2|}}}| 1 = [[Российская академия образования|член-корреспондент АПН СССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АПН СССР]]}}| 0 = [[Российская академия образования|академик АПН СССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики АПН СССР]]}}|<!--пустое значение-->}} <!-- Академия педагогических наук СССР (1966—1992) --> | ВАСХНИЛ = {{#switch: {{{2|}}}| 1 = [[Список членов-корреспондентов ВАСХНИЛ и РАСХН|член-корреспондент ВАСХНИЛ]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты ВАСХНИЛ]]}}| 0 = [[Всесоюзная академия сельскохозяйственных наук имени Ленина|академик ВАСХНИЛ]]{{#if:{{NAMESPACE}}||[[Категория:Академики ВАСХНИЛ]]}}|<!--пустое значение-->}} <!-- ВАСХНИЛ (1929—1992) --> | АА СССР = {{#switch: {{{2|}}}| 1 = [[Российская академия архитектуры и строительных наук|член-корреспондент АА СССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АА СССР]]}}| 0 = [[Российская академия архитектуры и строительных наук|академик АА СССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики Академии архитектуры СССР]]}}|<!--пустое значение-->}} <!-- Академия архитектуры СССР (1934—1956) и Академия строительства и архитектуры СССР (1956—1964) --> | АХ СССР = {{#switch: {{{2|}}}| 1 = [[Академия художеств СССР|член-корреспондент АХ СССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты Академии художеств СССР]]}}| 0 = [[Академия художеств СССР|академик АХ СССР]]{{#if:{{NAMESPACE}}||[[Категория:Действительные члены Академии художеств СССР]]}}|<!--пустое значение-->}} <!-- Академия художеств СССР республики ССР --> | АН АзССР = {{#switch: {{{2|}}}| 1 = [[Национальная академия наук Азербайджана|член-корреспондент АН Азербайджанской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН Азербайджанской ССР]]}}| 0 = [[Национальная академия наук Азербайджана|академик АН Азербайджанской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики АН Азербайджанской ССР]]}}|<!--пустое значение-->}} <!-- Академия наук Азербайджанской ССР --> | АН АрмССР = {{#switch: {{{2|}}}| 1 = [[Национальная академия наук Республики Армения|член-корреспондент АН Армянской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН Армянской ССР]]}}| 0 = [[Действительные члены НАН Армении за всю историю существования|академик АН Армянской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики АН Армянской ССР]]}}|<!--пустое значение-->}} <!-- Академия наук Армянской ССР --> | АН БССР = {{#switch: {{{2|}}}| 1 = [[Национальная академия наук Беларуси|член-корреспондент АН БССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты Академии наук Белорусской ССР]]}}| 0 = [[Национальная академия наук Беларуси|академик АН БССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики Академии наук Белорусской ССР]]}}|<!--пустое значение-->}} <!-- Белорусская академия наук в 1928-1936 гг.; Академия наук Белорусской ССР в 1936-1991 гг. --> | АН ГрузССР = {{#switch: {{{2|}}}| 1 = [[Национальная академия наук Грузии|член-корреспондент АН Грузинской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН Грузинской ССР‎]]}}| 0 = [[Национальная академия наук Грузии|академик АН Грузинской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики АН Грузинской ССР]]}}|<!--пустое значение-->}} <!-- Академия наук Грузинской ССР --> | АН МССР = {{#switch: {{{2|}}}| 1 = [[Академия наук Молдавии|член-корреспондент АН МССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН Молдавской ССР]]}}| 0 = [[Академия наук Молдавии|академик АН МССР]]{{#if:{{NAMESPACE}}||[[Категория:Действительные члены Академии наук Молдавской ССР]]}}|<!--пустое значение-->}} <!-- Академия наук Молдавской ССР --> | АН КазССР = {{#switch: {{{2|}}}| 1 = [[Национальная академия наук Казахстана|член-корреспондент АН Казахской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН Казахской ССР]]}}| 0 = [[Национальная академия наук Казахстана|академик АН Казахской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики АН Казахской ССР]]}}|<!--пустое значение-->}} <!-- Академия наук Казахской ССР --> | АН КиргССР = {{#switch: {{{2|}}}| 1 = [[Национальная академия наук Кыргызской Республики|член-корреспондент АН Киргизской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН Киргизской ССР]]}}| 0 = [[Национальная академия наук Кыргызской Республики|академик АН Киргизской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики АН Киргизской ССР]]}}|<!--пустое значение-->}} <!-- Академия наук Киргизской ССР --> | АН ЛатССР = {{#switch: {{{2|}}}| 1 = [[Академия наук Латвии|член-корреспондент АН Латвийской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН Латвийской ССР]]}}| 0 = [[Академия наук Латвии|академик АН Латвийской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики АН Латвийской ССР]]}}|<!--пустое значение-->}} <!-- Академия наук Латвийской ССР --> | АН ЛитССР = {{#switch: {{{2|}}}| 1 = [[Академия наук Литвы|член-корреспондент АН Литовской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН Литовской ССР]]}}| 0 = [[Академия наук Литвы|академик АН Литовской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики АН Литовской ССР]]}}|<!--пустое значение-->}} <!-- Академия наук Литовской ССР --> | АН УзССР = {{#switch: {{{2|}}}| 1 = [[Академия наук Узбекистана|член-корреспондент АН Узбекской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН Узбекской ССР]]}}| 0 = [[Академия наук Узбекистана|академик АН Узбекской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики АН Узбекской ССР]]}}|<!--пустое значение-->}} <!-- Академия наук Узбекской ССР --> | АН УССР = {{#switch: {{{2|}}}| 1 = [[Национальная академия наук Украины|член-корреспондент АН УССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН УССР]]}}| 0 = [[Национальная академия наук Украины|академик АН УССР]]{{#if:{{NAMESPACE}}||[[Категория:Действительные члены АН УССР]]}}|<!--пустое значение-->}}<!-- Академия наук Украинской ССР --> | АН ЭССР = {{#switch: {{{2|}}}| 1 = [[Эстонская академия наук|член-корреспондент АН ЭССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН Эстонской ССР]]}}| 0 = [[Эстонская академия наук|академик АН ЭССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики АН Эстонской ССР]]}}|<!--пустое значение-->}} <!-- Академия наук Эстонской ССР --> | АПН РСФСР = {{#switch: {{{2|}}}| 1 = [[Российская академия образования|член-корреспондент АПН РСФСР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АПН РСФСР]]}}| 0 = [[Российская академия образования|действительный член АПН РСФСР]]{{#if:{{NAMESPACE}}||[[Категория:Академики АПН РСФСР]]}}|<!--пустое значение-->}} <!-- Академия педагогических наук РСФСР --> | АН ТаджССР = {{#switch: {{{2|}}}| 1 = [[Академия наук Республики Таджикистан|член-корреспондент АН Таджикской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН Таджикской ССР]]}}| 0 = [[Академия наук Республики Таджикистан|действительный член АН Таджикской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики АН Таджикской ССР]]}}|<!--пустое значение-->}} <!-- Академия наук Таджикской ССР --> | АН ТуркССР = {{#switch: {{{2|}}}| 1 = [[Академия наук Туркмении|член-корреспондент АН Туркменской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН Туркменской ССР]]}}| 0 = [[Академия наук Туркмении|действительный член АН Туркменской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики АН Туркменской ССР]]}}|<!--пустое значение-->}} <!-- Академия наук Туркменской ССР --> <!-- постсоветские страны --> | НАНБ | АНБ = {{#switch: {{{2|}}}| 1 = [[Национальная академия наук Беларуси|член-корреспондент НАНБ]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты Национальной академии наук Беларуси]]}}| 0 = [[Национальная академия наук Беларуси|академик НАНБ]]{{#if:{{NAMESPACE}}||[[Категория:Академики Национальной академии наук Беларуси]]}}|<!--пустое значение-->}} <!-- Академия наук Беларуси в 1991—1997 гг (АНБ); Национальная академия наук Беларуси (НАН Беларуси, или НАНБ) с 1997 --> | АНМ = {{#switch: {{{2|}}}| 1 = [[Академия наук Молдавии|член-корреспондент АНМ]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АНМ]]}}| 0 = [[Академия наук Молдавии|академик АНМ]]{{#if:{{NAMESPACE}}||[[Категория:Академики Молдовы]]}}|<!--пустое значение-->}} | ААНБ = {{#switch: {{{2|}}}| 1 = [[Академия аграрных наук Беларуси|член-корреспондент ААНБ]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты ААНБ]]}}| 0 = [[Академия аграрных наук Беларуси|академик ААНБ]]{{#if:{{NAMESPACE}}||[[Категория:Академики ААНБ]]}}|<!--пустое значение-->}} <!-- Академия аграрных наук Беларуси (ААН Беларуси) --> | НАН РК = {{#switch: {{{2|}}}| 1 = [[Национальная академия наук Казахстана|член-корреспондент НАН РК]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты НАН Казахстана]]}}| 0 = [[Национальная академия наук Казахстана|академик НАН РК]]{{#if:{{NAMESPACE}}||[[Категория:Академики НАН Казахстана]]}}|<!--пустое значение-->}} <!-- Академия наук Казахстана --> | НАН КР = {{#switch: {{{2|}}}| 1 = [[Национальная академия наук Кыргызской Республики|член-корреспондент НАН КР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты НАН Кыргызстана]]}}| 0 = [[Национальная академия наук Кыргызской Республики|академик НАН КР]]{{#if:{{NAMESPACE}}||[[Категория:Академики НАН Кыргызстана]]}}|<!--пустое значение-->}} <!-- Академия наук Кыргызстана--> | НАН РА = {{#switch: {{{2|}}}| 1 = [[Национальная академия наук Республики Армения|член-корреспондент НАН РА]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты НАН Армении]]}}| 0 = [[Действительные члены НАН Армении за всю историю существования|академик НАН РА]]{{#if:{{NAMESPACE}}||[[Категория:Академики НАН Армении]]}}|<!--пустое значение-->}} <!-- Национальная академия наук Армении --> | НАНА = {{#switch: {{{2|}}}| 1 = [[Национальная академия наук Азербайджана|член-корреспондент НАНА]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты НАН Азербайджана]]}}| 0 = [[Национальная академия наук Азербайджана|академик НАНА]]{{#if:{{NAMESPACE}}||[[Категория:Академики НАН Азербайджана]]}}|<!--пустое значение-->}} <!-- Национальная академия наук Азербайджана --> | НАНУ = {{#switch: {{{2|}}}| 1 = [[Национальная академия наук Украины|член-корреспондент НАНУ]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты НАН Украины]]}}| 0 = [[Национальная академия наук Украины|академик НАНУ]]{{#if:{{NAMESPACE}}||[[Категория:Действительные члены НАН Украины]]}}|<!--пустое значение-->}} <!-- Национальная академия наук Украины --> | НАМНУ = {{#switch: {{{2|}}}| 1 = [[Национальная академия медицинских наук Украины|член-корреспондент НАМНУ]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты Национальной академии медицинских наук Украины]]}}| 0 = [[Национальная академия медицинских наук Украины|академик НАМНУ]]{{#if:{{NAMESPACE}}||[[Категория:Академики Национальной академии медицинских наук Украины]]}}|<!--пустое значение-->}} <!-- Национальная академия медицинских наук Украины --> | СПбАН = {{#switch: {{{2|}}}| 1 = [[Петербургская академия наук|член-корреспондент СПбАН]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты Петербургской академии наук]]}}| 0 = [[Петербургская академия наук|академик СПбАН]]{{#if:{{NAMESPACE}}||[[Категория:Действительные члены Петербургской академии наук]]}}|<!--пустое значение-->}} <!-- Петербургская академия наук --> | ПАН = {{#switch: {{{2|}}}| 1 = [[Польская академия наук|член-корреспондент ПАН]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты Польской академии наук]]}}| 0 = [[Польская академия наук|действительный член ПАН]]{{#if:{{NAMESPACE}}||[[Категория:Действительные члены Польской академии наук]]}}| 2 = [[Польская академия наук|иностранный член ПАН]]{{#if:{{NAMESPACE}}||[[Категория:Иностранные члены Польской академии наук‎]]}}| 3 = [[Польская академия наук|сотрудник ПАН]]{{#if:{{NAMESPACE}}||[[Категория:Сотрудники Польской академии наук‎]]}}|<!--пустое значение-->}} <!-- Польская академия наук --> | НАПНУ = {{#switch: {{{2|}}}| 1 = [[Национальная академия педагогических наук Украины|член-корреспондент НАПНУ]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты Национальной академии педагогических наук Украины]]}}| 0 = [[Национальная академия педагогических наук Украины|действительный член НАПНУ]]{{#if:{{NAMESPACE}}||[[Категория:Академики Национальной академии педагогических наук Украины]]}}|<!--пустое значение-->}} <!-- Национальная академия педагогических наук Украины --> | НАПрНУ = {{#switch: {{{2|}}}| 1 = [[Национальная академия правовых наук Украины|член-корреспондент НАПрНУ]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты Национальной академии правовых наук Украины]]}}| 0 = [[Национальная академия правовых наук Украины|действительный член НАПрНУ]]{{#if:{{NAMESPACE}}||[[Категория:Академики Национальной академии правовых наук Украины]]}}|<!--пустое значение-->}} <!-- Национальная академия правовых наук Украины --> | НАН Грузии = {{#switch: {{{2|}}}| 1 = [[Национальная академия наук Грузии|член-корреспондент НАН Грузии]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты Академии наук Грузии]]}}| 0 = [[Национальная академия наук Грузии|действительный член НАН Грузии]]{{#if:{{NAMESPACE}}||[[Категория:Академики Академии наук Грузии‎]]}}|<!--пустое значение-->}} <!-- Национальная академия наук Грузии--> | АН Узбекистана = {{#switch: {{{2|}}}| 1 = [[Академия наук Узбекистана|член-корреспондент АН Узбекистана]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН Узбекистана]]}}| 0 = [[Академия наук Узбекистана|действительный член АН Узбекистана]]{{#if:{{NAMESPACE}}||[[Категория:Академики АН Узбекистана]]}}|<!--пустое значение-->}} <!-- Академия наук Узбекистана --> <!-- Научное звание --> | {{#switch: {{{2|}}}| 1 = [[доцент]]| доцент = [[доцент]]| 0 = [[профессор (звание)|профессор]] | профессор = [[профессор (звание)|профессор]] |<!--пустое значение-->}} <!-- не академики --> }}</includeonly><noinclude>{{doc}}</noinclude> c96f56648a68c3a7ea133f232c7bf1196d3fa462 Шаблон:Историческое государство 10 185 412 2024-02-12T11:22:03Z ruwiki>Stjn 0 [[ВП:×|отмена]]: зачем? напишите ту же информацию в имеющемся поле население wikitext text/x-wiki {{Карточка |имя = Историческое государство |from = {{{from|}}} |стиль_тела = width:28em; |стиль_заголовков = |вверху0 = {{#if: {{{статус|}}} | {{{статус}}} | Историческое государство }} |вверху = {{Карточка/название|{{{название|}}}|from={{{from|}}}}} |вверху2 = {{Карточка/оригинал названия|{{{самоназвание|}}}|from={{{from|}}}}} |текст1 = {{Карточка/флаг и герб | флаг = {{{флаг|}}} | флаг подпись = {{{описание_флага|}}} | герб = {{{герб|}}} | герб подпись = {{{описание_герба|}}} |from={{{from|}}}}} |текст2 = {{#if: {{{девиз|}}} | [[Девиз]]: ''«{{{девиз}}}»''{{#if: {{{перевод девиза|}}}|<br />''«{{{перевод девиза}}}»''}} }} |текст3 = {{if-wikidata|p85|{{{гимн|}}}|[[Государственный гимн|Гимн]]: {{wikidata|p85|{{{гимн|}}}|from={{{from|}}}}}|from={{{from|}}}}} |викиданные3 = p85 |текст4 = {{wikidata|p242[1]|{{{карта|}}}|size={{{размер|}}}|caption={{{описание|}}}|from={{{from|}}}}} |заголовок5 = <div style="float:left; margin-right:0.5em; text-align:left; width:4em;"><!-- -->{{#if:{{{p8|}}}{{{successionbelow|}}}|[[#before-after|↓]]|<!-- -->{{#if:{{{p1|}}}|{{nobr|[[{{{p1}}}|←]]&nbsp;{{#if:{{{flag_p1|}}}|[[Файл:{{{flag_p1|}}}|border|30px|link={{{p1|}}}]]|{{#if:{{{image_p1|}}}|{{{image_p1}}}|[[Файл:Flag of None.svg|30px|border]]}}}}}}}}<!-- -->{{#if:{{{p2|}}}|<br>{{nobr|[[{{{p2}}}|←]]&nbsp;{{#if:{{{flag_p2|}}}|[[Файл:{{{flag_p2}}}|border|30px|link={{{p2|}}}]]|{{#if:{{{image_p2|}}}|{{{image_p2}}}|[[Файл:Flag of None.svg|30px|border]]}}}}}}}}<!-- -->{{#if:{{{p3|}}}|<br>{{nobr|[[{{{p3}}}|←]]&nbsp;{{#if:{{{flag_p3|}}}|[[Файл:{{{flag_p3}}}|border|30px|link={{{p3|}}}]]|{{#if:{{{image_p3|}}}|{{{image_p3}}}|[[Файл:Flag of None.svg|30px|border]]}}}}}}}}<!-- -->{{#if:{{{p4|}}}|<br>{{nobr|[[{{{p4}}}|←]]&nbsp;{{#if:{{{flag_p4|}}}|[[Файл:{{{flag_p4}}}|border|30px|link={{{p4|}}}]]|{{#if:{{{image_p4|}}}|{{{image_p4}}}|[[Файл:Flag of None.svg|30px|border]]}}}}}}}}<!-- -->{{#if:{{{p5|}}}|<br>{{nobr|[[{{{p5}}}|←]]&nbsp;{{#if:{{{flag_p5|}}}|[[Файл:{{{flag_p5}}}|border|30px|link={{{p5|}}}]]|{{#if:{{{image_p5|}}}|{{{image_p5}}}|[[Файл:Flag of None.svg|30px|border]]}}}}}}}}<!-- -->{{#if:{{{p6|}}}|<br>{{nobr|[[{{{p6}}}|←]]&nbsp;{{#if:{{{flag_p6|}}}|[[Файл:{{{flag_p6}}}|border|30px|link={{{p6|}}}]]|{{#if:{{{image_p6|}}}|{{{image_p6}}}|[[Файл:Flag of None.svg|30px|border]]}}}}}}}}<!-- -->{{#if:{{{p7|}}}|<br>{{nobr|[[{{{p7}}}|←]]&nbsp;{{#if:{{{flag_p7|}}}|[[Файл:{{{flag_p7}}}|border|30px|link={{{p7|}}}]]|{{#if:{{{image_p7|}}}|{{{image_p7}}}|[[Файл:Flag of None.svg|30px|border]]}}}}}}}}}}<!-- --></div> <div style="float:right; margin-left:0.5em; text-align:right; width:4em;"><!-- -->{{#if:{{{s8|}}}{{{successionbelow|}}}|[[#before-after|↓]]|<!-- -->{{#if:{{{s1|}}}|{{nobr|{{#if:{{{flag_s1|}}}|[[Файл:{{{flag_s1}}}|border|30px|link={{{s1|}}}]]|{{#if:{{{image_s1|}}}|{{{image_s1}}}|[[Файл:Flag of None.svg|30px|border]]}}}}&nbsp;[[{{{s1}}}|→]]}}}}<!-- -->{{#if:{{{s2|}}}|<br>{{nobr|{{#if:{{{flag_s2|}}}|[[Файл:{{{flag_s2}}}|border|30px|link={{{s2|}}}]]|{{#if:{{{image_s2|}}}|{{{image_s2}}}|[[Файл:Flag of None.svg|30px|border]]}}}}&nbsp;[[{{{s2}}}|→]]}}}}<!-- -->{{#if:{{{s3|}}}|<br>{{nobr|{{#if:{{{flag_s3|}}}|[[Файл:{{{flag_s3}}}|border|30px|link={{{s3|}}}]]|{{#if:{{{image_s3|}}}|{{{image_s3}}}|[[Файл:Flag of None.svg|30px|border]]}}}}&nbsp;[[{{{s3}}}|→]]}}}}<!-- -->{{#if:{{{s4|}}}|<br>{{nobr|{{#if:{{{flag_s4|}}}|[[Файл:{{{flag_s4}}}|border|30px|link={{{s4|}}}]]|{{#if:{{{image_s4|}}}|{{{image_s4}}}|[[Файл:Flag of None.svg|30px|border]]}}}}&nbsp;[[{{{s4}}}|→]]}}}}<!-- -->{{#if:{{{s5|}}}|<br>{{nobr|{{#if:{{{flag_s5|}}}|[[Файл:{{{flag_s5}}}|border|30px|link={{{s5|}}}]]|{{#if:{{{image_s5|}}}|{{{image_s5}}}|[[Файл:Flag of None.svg|30px|border]]}}}}&nbsp;[[{{{s5}}}|→]]}}}}<!-- -->{{#if:{{{s6|}}}|<br>{{nobr|{{#if:{{{flag_s6|}}}|[[Файл:{{{flag_s6}}}|border|30px|link={{{s6|}}}]]|{{#if:{{{image_s6|}}}|{{{image_s6}}}|[[Файл:Flag of None.svg|30px|border]]}}}}&nbsp;[[{{{s6}}}|→]]}}}}<!-- -->{{#if:{{{s7|}}}|<br>{{nobr|{{#if:{{{flag_s7|}}}|[[Файл:{{{flag_s7}}}|border|30px|link={{{s7|}}}]]|{{#if:{{{image_s7|}}}|{{{image_s7}}}|[[Файл:Flag of None.svg|30px|border]]}}}}&nbsp;[[{{{s7}}}|→]]}}}}}}<!-- --></div> {{#if: {{wikidata|p571|{{{образовано|}}}|plain=true|from={{{from|}}}}} {{wikidata|p576|{{{ликвидировано|}}}|plain=true|from={{{from|}}}}} | <div style="margin:0 4em;">{{nobr|{{wikidata|p571|{{{образовано|}}}|from={{{from|}}}}}&nbsp;—}} {{nobr|{{wikidata|p576|{{{ликвидировано|}}}|from={{{from|}}}}}}}</div> }} {{-}} |метка6 = [[Столица]] |текст6 = {{{столица|}}} |викиданные6 = p36 |метка7 = Крупнейшие города |текст7 = {{{города|}}} |викиданные7 = |метка8 = Язык(и) |текст8 = {{{язык|}}} |викиданные8 = p2936 |метка9 = [[Официальный язык]] |текст9 = {{{официальный язык|}}} |викиданные9 = p37 |метка10 = [[Религия]] |текст10 = {{{религия|}}} |викиданные10 = p3075 |метка11 = Денежная единица |текст11 = {{{валюта|}}} |викиданные11 = p38 |метка12 = Площадь |текст12 = {{{площадь|}}} |викиданные12 = p2046 |метка13 = Население |текст13 = {{{население|}}} |викиданные13 = p1082 |метка14 = Форма правления |текст14 = {{{форма_правления|}}} |викиданные14 = p122 |метка15 = Династия |текст15 = {{{династия|}}} |викиданные15 = |метка16 = {{{дополнительный_параметр}}} |текст16 = {{{содержимое_параметра|}}} |викиданные16 = |метка17 = {{{дополнительный_параметр1}}} |текст17 = {{{содержимое_параметра1|}}} |викиданные17 = |метка18 = {{{дополнительный_параметр2}}} |текст18 = {{{содержимое_параметра2|}}} |викиданные18 = |метка19 = {{{дополнительный_параметр3}}} |текст19 = {{{содержимое_параметра3|}}} |викиданные19 = |метка20 = {{{дополнительный_параметр4}}} |текст20 = {{{содержимое_параметра4|}}} |викиданные20 = |метка21 = {{{дополнительный_параметр5}}} |текст21 = {{{содержимое_параметра5|}}} |викиданные21 = |метка22 = {{{дополнительный_параметр6}}} |текст22 = {{{содержимое_параметра6|}}} |викиданные22 = |заголовок23 = {{#if: {{{титул_правителей2|}}}{{{титул_правителей3|}}}{{{титул_правителей4|}}}{{{титул_правителей5|}}}{{{титул_правителей6|}}}{{{титул_правителей7|}}}{{{титул_правителей8|}}}{{{титул_правителей9|}}}{{{титул_правителей10|}}}{{{титул_правителей11|}}}{{{титул_правителей12|}}}{{{титул_правителей13|}}}{{{титул_правителей14|}}}{{{титул_правителей15|}}}{{{титул_правителей16|}}} | Главы государства }} |заголовок24 = {{#if: {{{правитель1|}}} | {{{титул_правителя1|{{{титул_правителей}}}}}} }} |стиль_заголовка24 = {{#if: {{{титул_правителей2|}}}{{{титул_правителей3|}}}{{{титул_правителей4|}}}{{{титул_правителей5|}}}{{{титул_правителей6|}}}{{{титул_правителей7|}}}{{{титул_правителей8|}}}{{{титул_правителей9|}}}{{{титул_правителей10|}}}{{{титул_правителей11|}}}{{{титул_правителей12|}}}{{{титул_правителей13|}}}{{{титул_правителей14|}}}{{{титул_правителей15|}}}{{{титул_правителей16|}}} | background: transparent; padding-bottom:0; border-bottom:0; text-align:left; }} |метка25 = &nbsp;•&nbsp;{{{год_правителя1}}} |стиль_метки25 = font-weight:normal; {{#if: {{{титул_правителей2|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |текст25 = {{{правитель1|}}} |стиль_текста25 = {{#if: {{{титул_правителей2|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |викиданные25 = |заголовок26 = {{{титул_правителей2|}}} |стиль_заголовка26 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left; |метка27 = &nbsp;•&nbsp;{{{год_правителя2}}} |стиль_метки27 = font-weight:normal; {{#if: {{{титул_правителей3|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |текст27 = {{{правитель2|}}} |стиль_текста27 = {{#if: {{{титул_правителей3|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |викиданные27 = |заголовок28 = {{{титул_правителей3|}}} |стиль_заголовка28 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left; |метка29 = &nbsp;•&nbsp;{{{год_правителя3}}} |стиль_метки29 = font-weight:normal; {{#if: {{{титул_правителей4|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |текст29 = {{{правитель3|}}} |стиль_текста29 = {{#if: {{{титул_правителей4|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |викиданные29 = |заголовок30 = {{{титул_правителей4|}}} |стиль_заголовка30 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left; |метка31 = &nbsp;•&nbsp;{{{год_правителя4}}} |стиль_метки31 = font-weight:normal; {{#if: {{{титул_правителей5|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |текст31 = {{{правитель4|}}} |стиль_текста31 = {{#if: {{{титул_правителей5|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |викиданные31 = |заголовок32 = {{{титул_правителей5|}}} |стиль_заголовка32 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left; |метка33 = &nbsp;•&nbsp;{{{год_правителя5}}} |стиль_метки33 = font-weight:normal; {{#if: {{{титул_правителей6|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |текст33 = {{{правитель5|}}} |стиль_текста33 = {{#if: {{{титул_правителей6|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |викиданные33 = |заголовок34 = {{{титул_правителей6|}}} |стиль_заголовка34 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left; |метка35 = &nbsp;•&nbsp;{{{год_правителя6}}} |стиль_метки35 = font-weight:normal; {{#if: {{{титул_правителей7|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |текст35 = {{{правитель6|}}} |стиль_текста35 = {{#if: {{{титул_правителей7|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |викиданные35 = |заголовок36 = {{{титул_правителей7|}}} |стиль_заголовка36 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left; |метка37 = &nbsp;•&nbsp;{{{год_правителя7}}} |стиль_метки37 = font-weight:normal; {{#if: {{{титул_правителей8|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |текст37 = {{{правитель7|}}} |стиль_текста37 = {{#if: {{{титул_правителей8|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |викиданные37 = |заголовок38 = {{{титул_правителей8|}}} |стиль_заголовка38 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left; |метка39 = &nbsp;•&nbsp;{{{год_правителя8}}} |стиль_метки39 = font-weight:normal; {{#if: {{{титул_правителей9|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |текст39 = {{{правитель8|}}} |стиль_текста39 = {{#if: {{{титул_правителей9|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |викиданные39 = |заголовок40 = {{{титул_правителей9|}}} |стиль_заголовка40 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left; |метка41 = &nbsp;•&nbsp;{{{год_правителя9}}} |стиль_метки41 = font-weight:normal; {{#if: {{{титул_правителей10|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |текст41 = {{{правитель9|}}} |стиль_текста41 = {{#if: {{{титул_правителей10|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |викиданные41 = |заголовок42 = {{{титул_правителей10|}}} |стиль_заголовка42 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left; |метка43 = &nbsp;•&nbsp;{{{год_правителя10}}} |стиль_метки43 = font-weight:normal; {{#if: {{{титул_правителей11|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |текст43 = {{{правитель10|}}} |стиль_текста43 = {{#if: {{{титул_правителей11|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |викиданные43 = |заголовок44 = {{{титул_правителей11|}}} |стиль_заголовка44 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left; |метка45 = &nbsp;•&nbsp;{{{год_правителя11}}} |стиль_метки45 = font-weight:normal; {{#if: {{{титул_правителей12|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |текст45 = {{{правитель11|}}} |стиль_текста45 = {{#if: {{{титул_правителей12|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |викиданные45 = |заголовок46 = {{{титул_правителей12|}}} |стиль_заголовка46 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left; |метка47 = &nbsp;•&nbsp;{{{год_правителя12}}} |стиль_метки47 = font-weight:normal; {{#if: {{{титул_правителей13|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |текст47 = {{{правитель12|}}} |стиль_текста47 = {{#if: {{{титул_правителей13|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |викиданные47 = |заголовок48 = {{{титул_правителей13|}}} |стиль_заголовка48 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left; |метка49 = &nbsp;•&nbsp;{{{год_правителя13}}} |стиль_метки49 = font-weight:normal; {{#if: {{{титул_правителей14|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |текст49 = {{{правитель13|}}} |стиль_текста49 = {{#if: {{{титул_правителей14|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |викиданные49 = |заголовок50 = {{{титул_правителей14|}}} |стиль_заголовка50 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left; |метка51 = &nbsp;•&nbsp;{{{год_правителя14}}} |стиль_метки51 = font-weight:normal; {{#if: {{{титул_правителей15|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |текст51 = {{{правитель14|}}} |стиль_текста51 = {{#if: {{{титул_правителей15|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |викиданные51 = |заголовок52 = {{{титул_правителей15|}}} |стиль_заголовка52 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left; |метка53 = &nbsp;•&nbsp;{{{год_правителя15}}} |стиль_метки53 = font-weight:normal; {{#if: {{{титул_правителей16|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |текст53 = {{{правитель15|}}} |стиль_текста53 = {{#if: {{{титул_правителей16|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |викиданные53 = |заголовок54 = {{{титул_правителей16|}}} |стиль_заголовка54 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left; |метка55 = &nbsp;•&nbsp;{{{год_правителя16}}} |стиль_метки55 = font-weight:normal; padding-top:0; border-top:0; |текст55 = {{{правитель16|}}} |стиль_текста55 = padding-top:0; border-top:0; |викиданные55 = |заголовок56 = {{#if: {{{Этап1|}}} | История }} |метка57 = &nbsp;•&nbsp;{{nobr|{{{Дата1|}}}{{#if: {{{Дата1|}}} | {{sp}} }}{{{Год1|}}}}} |стиль_метки57 = font-weight:normal; {{#if: {{{Этап2|}}} | padding-bottom:0; border-bottom:0;}} |текст57 = {{{Этап1|}}} |стиль_текста57 = {{#if: {{{Этап2|}}} | padding-bottom:0; border-bottom:0;}} |викиданные57 = |метка58 = &nbsp;•&nbsp;{{nobr|{{{Дата2|}}}{{#if: {{{Дата2|}}} | {{sp}} }}{{{Год2|}}}}} |стиль_метки58 = font-weight:normal; {{#if: {{{Этап3|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |текст58 = {{{Этап2|}}} |стиль_текста58 = {{#if: {{{Этап3|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |викиданные58 = |метка59 = &nbsp;•&nbsp;{{nobr|{{{Дата3|}}}{{#if: {{{Дата3|}}} | {{sp}} }}{{{Год3|}}}}} |стиль_метки59 = font-weight:normal; {{#if: {{{Этап4|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |текст59 = {{{Этап3|}}} |стиль_текста59 = {{#if: {{{Этап4|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |викиданные59 = |метка60 = &nbsp;•&nbsp;{{nobr|{{{Дата4|}}}{{#if: {{{Дата4|}}} | {{sp}} }}{{{Год4|}}}}} |стиль_метки60 = font-weight:normal; {{#if: {{{Этап5|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |текст60 = {{{Этап4|}}} |стиль_текста60 = {{#if: {{{Этап5|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |викиданные60 = |метка61 = &nbsp;•&nbsp;{{nobr|{{{Дата5|}}}{{#if: {{{Дата5|}}} | {{sp}} }}{{{Год5|}}}}} |стиль_метки61 = font-weight:normal; {{#if: {{{Этап6|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |текст61 = {{{Этап5|}}} |стиль_текста61 = {{#if: {{{Этап6|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |викиданные61 = |метка62 = &nbsp;•&nbsp;{{nobr|{{{Дата6|}}}{{#if: {{{Дата6|}}} | {{sp}} }}{{{Год6|}}}}} |стиль_метки62 = font-weight:normal; {{#if: {{{Этап7|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |текст62 = {{{Этап6|}}} |стиль_текста62 = {{#if: {{{Этап7|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |викиданные62 = |метка63 = &nbsp;•&nbsp;{{nobr|{{{Дата7|}}}{{#if: {{{Дата7|}}} | {{sp}} }}{{{Год7|}}}}} |стиль_метки63 = font-weight:normal; {{#if: {{{Этап8|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |текст63 = {{{Этап7|}}} |стиль_текста63 = {{#if: {{{Этап8|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |викиданные63 = |метка64 = &nbsp;•&nbsp;{{nobr|{{{Дата8|}}}{{#if: {{{Дата8|}}} | {{sp}} }}{{{Год8|}}}}} |стиль_метки64 = font-weight:normal; {{#if: {{{Этап9|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |текст64 = {{{Этап8|}}} |стиль_текста64 = {{#if: {{{Этап9|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |викиданные64 = |метка65 = &nbsp;•&nbsp;{{nobr|{{{Дата9|}}}{{#if: {{{Дата9|}}} | {{sp}} }}{{{Год9|}}}}} |стиль_метки65 = font-weight:normal; {{#if: {{{Этап10|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |текст65 = {{{Этап9|}}} |стиль_текста65 = {{#if: {{{Этап10|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |викиданные65 = |метка66 = &nbsp;•&nbsp;{{nobr|{{{Дата10|}}}{{#if: {{{Дата10|}}} | {{sp}} }}{{{Год10|}}}}} |стиль_метки66 = font-weight:normal; {{#if: {{{Этап11|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |текст66 = {{{Этап10|}}} |стиль_текста66 = {{#if: {{{Этап11|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |викиданные66 = |метка67 = &nbsp;•&nbsp;{{nobr|{{{Дата11|}}}{{#if: {{{Дата11|}}} | {{sp}} }}{{{Год11|}}}}} |стиль_метки67 = font-weight:normal; padding-top:0; border-top:0; |текст67 = {{{Этап11|}}} |стиль_текста67 = padding-top:0; border-top:0; |викиданные67 = |заголовок68 = {{#if: {{{до|}}}{{{после|}}} | Преемственность }} |текст69 = {{#if: {{{до|}}} | ←&nbsp;[[{{{до}}}]] {{#if: {{{д1|}}} | ←&nbsp;[[{{{д1}}}]] }} {{#if: {{{д2|}}} | ←&nbsp;[[{{{д2}}}]] }} {{#if: {{{д3|}}} | ←&nbsp;[[{{{д3}}}]] }} {{#if: {{{д4|}}} | ←&nbsp;[[{{{д4}}}]] }} {{#if: {{{д5|}}} | ←&nbsp;[[{{{д5}}}]] }} {{#if: {{{д6|}}} | ←&nbsp;[[{{{д6}}}]] }} {{#if: {{{д7|}}} | ←&nbsp;[[{{{д7}}}]] }} }} |стиль_текста69 = text-align:left; |текст70 = {{#if: {{{после|}}} | [[{{{после}}}]]&nbsp;→ {{#if: {{{п1|}}} | [[{{{п1}}}]]&nbsp;→ }} {{#if: {{{п2|}}} | [[{{{п2}}}]]&nbsp;→ }} {{#if: {{{п3|}}} | [[{{{п3}}}]]&nbsp;→ }} {{#if: {{{п4|}}} | [[{{{п4}}}]]&nbsp;→ }} {{#if: {{{п5|}}} | [[{{{п5}}}]]&nbsp;→ }} {{#if: {{{п6|}}} | [[{{{п6}}}]]&nbsp;→ }} {{#if: {{{п7|}}} | [[{{{п7}}}]]&nbsp;→ }} }} |стиль_текста70 = text-align:right; |заголовок71 = {{#ifeq: {{#expr: {{#expr:{{#if:{{{p8|}}}|1|0}}+{{#if:{{{s8|}}}|1|0}}}}+{{#if:{{{successionbelow|}}}|1|0}} > 0}} | 1 | {{Видимый якорь|before-after|текст=Предшественники и преемники}} }} |текст72 = {{#ifeq: {{#expr: {{#expr:{{#if:{{{p8|}}}|1|0}}+{{#if:{{{s8|}}}|1|0}}}}+{{#if:{{{successionbelow|}}}|1|0}} > 0}} | 1 | <table style="display:table; margin:0; padding:0; table-layout:fixed; width:100%;"> <tr> <td style="padding-left:0;">{{#if: {{{p1|}}}{{{successionbelow|}}} | {{#if: {{{type_before|}}}{{{type_after|}}} | '''{{{type_before|Предшественники}}}''' }} * {{#if:{{{flag_p1|}}}|[[Файл:{{{flag_p1}}}|20px|border]]|{{#if:{{{image_p1|}}}|{{{image_p1}}}}}}} [[{{{p1}}}]]<!-- -->{{#if: {{{p2|}}} | * {{#if:{{{flag_p2|}}}|[[Файл:{{{flag_p2}}}|20px|border]]|{{#if:{{{image_p2|}}}|{{{image_p2}}}}}}} [[{{{p2}}}]] }}<!-- -->{{#if: {{{p3|}}} | * {{#if:{{{flag_p3|}}}|[[Файл:{{{flag_p3}}}|20px|border]]|{{#if:{{{image_p3|}}}|{{{image_p3}}}}}}} [[{{{p3}}}]] }}<!-- -->{{#if: {{{p4|}}} | * {{#if:{{{flag_p4|}}}|[[Файл:{{{flag_p4}}}|20px|border]]|{{#if:{{{image_p4|}}}|{{{image_p4}}}}}}} [[{{{p4}}}]] }}<!-- -->{{#if: {{{p5|}}} | * {{#if:{{{flag_p5|}}}|[[Файл:{{{flag_p5}}}|20px|border]]|{{#if:{{{image_p5|}}}|{{{image_p5}}}}}}} [[{{{p5}}}]] }}<!-- -->{{#if: {{{p6|}}} | * {{#if:{{{flag_p6|}}}|[[Файл:{{{flag_p6}}}|20px|border]]|{{#if:{{{image_p6|}}}|{{{image_p6}}}}}}} [[{{{p6}}}]] }}<!-- -->{{#if: {{{p7|}}} | * {{#if:{{{flag_p7|}}}|[[Файл:{{{flag_p7}}}|20px|border]]|{{#if:{{{image_p7|}}}|{{{image_p7}}}}}}} [[{{{p7}}}]] }}<!-- -->{{#if: {{{p8|}}} | * {{#if:{{{flag_p8|}}}|[[Файл:{{{flag_p8}}}|20px|border]]|{{#if:{{{image_p8|}}}|{{{image_p8}}}}}}} [[{{{p8}}}]] }}<!-- -->{{#if: {{{p9|}}} | * {{#if:{{{flag_p9|}}}|[[Файл:{{{flag_p9}}}|20px|border]]|{{#if:{{{image_p9|}}}|{{{image_p9}}}}}}} [[{{{p9}}}]] }}<!-- -->{{#if: {{{p10|}}} | * {{#if:{{{flag_p10|}}}|[[Файл:{{{flag_p10}}}|20px|border]]|{{#if:{{{image_p10|}}}|{{{image_p10}}}}}}} [[{{{p10}}}]] }}<!-- -->{{#if: {{{p11|}}} | * {{#if:{{{flag_p11|}}}|[[Файл:{{{flag_p11}}}|20px|border]]|{{#if:{{{image_p11|}}}|{{{image_p11}}}}}}} [[{{{p11}}}]] }}<!-- -->{{#if: {{{p12|}}} | * {{#if:{{{flag_p12|}}}|[[Файл:{{{flag_p12}}}|20px|border]]|{{#if:{{{image_p12|}}}|{{{image_p12}}}}}}} [[{{{p12}}}]] }}<!-- -->{{#if: {{{p13|}}} | * {{#if:{{{flag_p13|}}}|[[Файл:{{{flag_p13}}}|20px|border]]|{{#if:{{{image_p13|}}}|{{{image_p13}}}}}}} [[{{{p13}}}]] }}<!-- -->{{#if: {{{p14|}}} | * {{#if:{{{flag_p14|}}}|[[Файл:{{{flag_p14}}}|20px|border]]|{{#if:{{{image_p14|}}}|{{{image_p14}}}}}}} [[{{{p14}}}]] }}<!-- -->{{#if: {{{p15|}}} | * {{#if:{{{flag_p15|}}}|[[Файл:{{{flag_p15}}}|20px|border]]|{{#if:{{{image_p15|}}}|{{{image_p15}}}}}}} [[{{{p15}}}]] }} }}</td> <td style="padding-right:0;">{{#if: {{{s1|}}}{{{successionbelow|}}} | {{#if: {{{type_before|}}}{{{type_after|}}} | '''{{{type_after|Преемники}}}''' }} * {{#if:{{{flag_s1|}}}|[[Файл:{{{flag_s1}}}|20px|border]]|{{#if:{{{image_s1|}}}|{{{image_s1}}}}}}} [[{{{s1}}}]]<!-- -->{{#if: {{{s2|}}} | * {{#if:{{{flag_s2|}}}|[[Файл:{{{flag_s2}}}|20px|border]]|{{#if:{{{image_s2|}}}|{{{image_s2}}}}}}} [[{{{s2}}}]] }}<!-- -->{{#if: {{{s3|}}} | * {{#if:{{{flag_s3|}}}|[[Файл:{{{flag_s3}}}|20px|border]]|{{#if:{{{image_s3|}}}|{{{image_s3}}}}}}} [[{{{s3}}}]] }}<!-- -->{{#if: {{{s4|}}} | * {{#if:{{{flag_s4|}}}|[[Файл:{{{flag_s4}}}|20px|border]]|{{#if:{{{image_s4|}}}|{{{image_s4}}}}}}} [[{{{s4}}}]] }}<!-- -->{{#if: {{{s5|}}} | * {{#if:{{{flag_s5|}}}|[[Файл:{{{flag_s5}}}|20px|border]]|{{#if:{{{image_s5|}}}|{{{image_s5}}}}}}} [[{{{s5}}}]] }}<!-- -->{{#if: {{{s6|}}} | * {{#if:{{{flag_s6|}}}|[[Файл:{{{flag_s6}}}|20px|border]]|{{#if:{{{image_s6|}}}|{{{image_s6}}}}}}} [[{{{s6}}}]] }}<!-- -->{{#if: {{{s7|}}} | * {{#if:{{{flag_s7|}}}|[[Файл:{{{flag_s7}}}|20px|border]]|{{#if:{{{image_s7|}}}|{{{image_s7}}}}}}} [[{{{s7}}}]] }}<!-- -->{{#if: {{{s8|}}} | * {{#if:{{{flag_s8|}}}|[[Файл:{{{flag_s8}}}|20px|border]]|{{#if:{{{image_s8|}}}|{{{image_s8}}}}}}} [[{{{s8}}}]] }}<!-- -->{{#if: {{{s9|}}} | * {{#if:{{{flag_s9|}}}|[[Файл:{{{flag_s9}}}|20px|border]]|{{#if:{{{image_s9|}}}|{{{image_s9}}}}}}} [[{{{s9}}}]] }}<!-- -->{{#if: {{{s10|}}} | * {{#if:{{{flag_s10|}}}|[[Файл:{{{flag_s10}}}|20px|border]]|{{#if:{{{image_s10|}}}|{{{image_s10}}}}}}} [[{{{s10}}}]] }}<!-- -->{{#if: {{{s11|}}} | * {{#if:{{{flag_s11|}}}|[[Файл:{{{flag_s11}}}|20px|border]]|{{#if:{{{image_s11|}}}|{{{image_s11}}}}}}} [[{{{s11}}}]] }}<!-- -->{{#if: {{{s12|}}} | * {{#if:{{{flag_s12|}}}|[[Файл:{{{flag_s12}}}|20px|border]]|{{#if:{{{image_s12|}}}|{{{image_s12}}}}}}} [[{{{s12}}}]] }}<!-- -->{{#if: {{{s13|}}} | * {{#if:{{{flag_s13|}}}|[[Файл:{{{flag_s13}}}|20px|border]]|{{#if:{{{image_s13|}}}|{{{image_s13}}}}}}} [[{{{s13}}}]] }}<!-- -->{{#if: {{{s14|}}} | * {{#if:{{{flag_s14|}}}|[[Файл:{{{flag_s14}}}|20px|border]]|{{#if:{{{image_s14|}}}|{{{image_s14}}}}}}} [[{{{s14}}}]] }}<!-- -->{{#if: {{{s15|}}} | * {{#if:{{{flag_s15|}}}|[[Файл:{{{flag_s15}}}|20px|border]]|{{#if:{{{image_s15|}}}|{{{image_s15}}}}}}} [[{{{s15}}}]] }} }}</td> </tr> </table> }} |стиль_текста72 = text-align:left; |текст73 = {{{прим|}}} |стиль_текста73 = border-top:1px solid #a2a9b1; color:#54595d; padding-top:0.5em; text-align:left; |внизу = {{карточка/Викисклад|{{{викисклад|}}}|from={{{from|}}}}} }}{{#if:{{NAMESPACE}}{{{nocat|}}}||<!-- -->{{категория по дате|{{{образовано|}}}|Государства и территории, основанные|p571|from={{{from|}}}}}<!-- -->{{категория по дате|{{{образовано2|}}}|Государства и территории, основанные|from={{{from|}}}}}<!-- -->{{категория по дате|{{{образовано3|}}}|Государства и территории, основанные|from={{{from|}}}}}<!-- -->{{категория по дате|{{{ликвидировано|}}}|Государства и территории, исчезнувшие|p576|from={{{from|}}}}}<!-- -->{{категория по дате|{{{ликвидировано2|}}}|Государства и территории, исчезнувшие|from={{{from|}}}}}<!-- -->{{категория по дате|{{{ликвидировано3|}}}|Государства и территории, исчезнувшие|from={{{from|}}}}}<!-- -->{{#ifeq:{{{флаг}}}|novalue|{{#if:{{wikidata|p41|from={{{from|}}}}}|[[Категория:Статьи со спорным параметром в Викиданных]]}}|}}{{#ifeq:{{{герб}}}|novalue|{{#if:{{if-wikidata|p94|from={{{from|}}}}}|[[Категория:Статьи со спорным параметром в Викиданных]]}}|}}<!-- -->}}<noinclude>{{doc}}</noinclude> 3f810e404f545118ca6d15a13a0a04829c1f3c88 Шаблон:Историческое государство/doc 10 191 428 2024-02-12T11:22:28Z ruwiki>Stjn 0 [[ВП:×|отмена]]: зачем? напишите ту же информацию в имеющемся поле население wikitext text/x-wiki {{docpage}} {{Переписать шаблон|меташаблон=Карточка/блок с маркерами}} Этот [[Википедия:Шаблоны-карточки|шаблон-карточка]] используется для вставки карточки в статьи об отдельных исторических государствах. * для современных государств используется {{t|государство}}. * для составных частей государств используется {{t|административная единица}}. == Заготовка, включающая все возможные параметры == <pre> {{Историческое государство |название = |самоназвание = |статус = |гимн = |флаг = |описание_флага = |герб = |описание_герба = |карта = |размер = |описание = <!-- |type_before = если этот параметр присутствует в шаблоне, то необходимо указать примерно следующее: «Государства-основатели», иначе удалите его, автоматически будет указано: «Предшественники».--> |p1 = |flag_p1 = |image_p1 = |p2 = |flag_p2 = |image_p2 = |p3 = |flag_p3 = |image_p3 = |p4 = |flag_p4 = |image_p4 = |образовано = |ликвидировано = <!-- |type_after = если этот параметр присутствует в шаблоне, то необходимо указать примерно следующее: «Государства после распада…», иначе удалите его, автоматически будет указано: «Преемники».--> |s1 = |flag_s1 = |image_s1 = |s2 = |flag_s2 = |image_s2 = |s3 = |flag_s3 = |image_s3 = |s4 = |flag_s4 = |image_s4 = |девиз = |столица = |города = |язык = |валюта = |дополнительный_параметр = |содержимое_параметра = |площадь = |население = |форма_правления = |династия = |титул_правителей = |правитель1 = <!--Не вставляйте в шаблон всех правителей, если их много — он не для этого! Создайте соответствующий раздел в статье. --> |год_правителя1 = |титул_правителей2 = <!--используется при изменении титула последующего правителя--> |правитель2 = |год_правителя2 = |титул_правителей3 = |правитель3 = |год_правителя3 = |титул_правителей4 = |правитель4 = |год_правителя4 = |титул_правителей5 = |правитель5 = |год_правителя5 = |титул_правителей6 = |правитель6 = |год_правителя6 = |религия = |дополнительный_параметр1 = |содержимое_параметра1 = |Этап1 = |Дата1 = |Год1 = |Этап2 = |Дата2 = |Год2 = |Этап3 = |Дата3 = |Год3 = |Этап4 = |Дата4 = |Год4 = |Этап5 = |Дата5 = |Год5 = |Этап6 = |Дата6 = |Год6 = |Этап7 = |Дата7 = |Год7 = |Этап8 = |Дата8 = |Год8 = |Этап9 = |Дата9 = |Год9 = |Этап10 = |Дата10 = |Год10 = |Этап11 = |Дата11 = |Год11 = |дополнительный_параметр2 = |содержимое_параметра2 = |до = |д1 = |д2 = |д3 = |д4 = |д5 = |д6 = |д7 = |после = |п1 = |п2 = |п3 = |п4 = |п5 = |п6 = |п7 = |прим = |викисклад = }} </pre> * ''Название'' — официальное наименование административной единицы (если административная единица имела несколько официальных наименований — указывается то, что применялось на протяжении наибольшего времени существования территории). * ''Самоназвание'' — название на официальном языке административной единицы. * ''Статус'' — административный статус единицы (царство, княжество, королевство и т. д.). * ''Гимн'' — гимн территории. Параметр поддерживает импорт викиданных. * ''Флаг'' — флаг территории. Параметр поддерживает импорт викиданных. Есть возможность [[ВП:ЛЖЕГЕРБ|выключить]], заполнив параметр текстом <code>novalue</code>. Для полного выключения полосы надо так же заполнить параметр ''Герб''. * ''описание_флага'' — Если не задано, по умолчанию отображается подпись Флаг. Подпись особенно полезна, если государство в разное время имело разл. флаги. * ''Герб'' — герб территории. Параметр поддерживает импорт викиданных. Есть возможность [[ВП:ЛЖЕГЕРБ|выключить]], заполнив параметр текстом <code>novalue</code>. Для полного выключения полосы надо так же заполнить параметр ''Флаг''. * ''описание_герба'' — Если не задано, по умолчанию отображается подпись Герб. Подпись особенно полезна, если государство в разное время имело разл. гербы. * ''Карта'' — карта территории, желательно, по наиболее позднему состоянию. Параметр поддерживает импорт викиданных. * ''размер'' — необязательное поле, по умолчанию = 270px * ''Описание'' — описание карты, заметки. * ''Девиз'' — девиз правящего дома либо государства. * ''type_before'' — если этот параметр присутствует в шаблоне, то необходимо указать примерно следующее: «Государства-основатели», иначе удалите его, автоматически будет указано: «Предшественники». * ''p1'' — название административной единицы, существовавшей на данной территории до создания предмета статьи (станет ссылкой). * ''flag_p1'' — флаг административной единицы, существовавшей на данной территории до создания предмета статьи. * ''image_pN '' — гербы и другие изображения, для которых нежелательна рамка (в формате <nowiki>[[File:...|Npx]]</nowiki>) * ''s1'' — название административной единицы, существовавшей на данной территории после упразднения предмета статьи (станет ссылкой). * ''flag_s1'' — флаг административной единицы, существовавшей на данной территории после упразднения предмета статьи. * ''image_sN '' — гербы и другие изображения, для которых нежелательна рамка (в формате <nowiki>[[File:...|Npx]]</nowiki>) * ''pN'' — другие предшественники (если более четырёх, используйте параметры «До» и «После»). * ''flag_sN'' — флаги государств-предшественников. * ''Образовано'' — год образования административной единицы. Параметр поддерживает импорт викиданных. * ''ликвидировано'' — год прекращения существования административной единицы. Параметр поддерживает импорт викиданных. * ''type_after'' — если этот параметр присутствует в шаблоне, то необходимо указать примерно следующее: «Государства после распада…», иначе удалите его, автоматически будет указано: «Преемники». * ''pN'' — другие преемники (если более четырёх, используйте параметры «До» и «После»). * ''flag_pN'' — флаги государств-преемников. * ''Столица'' — административный центр территории. Параметр поддерживает импорт викиданных. * ''Валюта'' — денежная единица данной территории. Параметр поддерживает импорт викиданных. * ''Города'' — крупнейшие города данной территории. * ''Язык'' — официальный язык территории. Параметр поддерживает импорт викиданных. * ''Форма_правления'' — форма правления на данной территории. Параметр поддерживает импорт викиданных. * ''титул_правителей'' — титулы правителей, заданных в параметрах правитель N. Например: «Короли». Если правители имели различные титулы, можно воспользоваться более общей формулировкой, например: «Основные правители». * ''титул_правителейN'' — используется при изменении титула последующего правителя. * ''правительN'' — имя правителя N * ''год_правителяN'' — годы правления правителя N * ''Дополнительный_параметр1, 2'' — название параметра. * ''Содержимое_параметра1, 2'' — содержимое параметра. * ''ЭтапN'' — название этапа в истории государства (до 11). * ''ДатаN'' — дата начала этапа (до 11). * ''ГодN'' — год начала этапа (до 11). * ''До'' — название административной единицы, существовавшей на данной территории до создания предмета статьи. * ''После'' — название административной единицы, существовавшей на данной территории после упразднения предмета статьи. * ''дN'' — другие предшественники (до 7). * ''пN'' — другие преемники (до 7). * ''прим'' — примечания. * ''викисклад'' — категория на Викискладе. <includeonly> [[Категория:Шаблоны-карточки:Географические объекты]] [[Категория:Шаблоны-карточки:История]] </includeonly> 56637e0862b3c305ebd1643f0787f74a89bf78cf Модуль:Navbox 828 82 138 2024-02-23T14:27:31Z ruwiki>Stjn 0 переход на [[модуль:Navbar]] Scribunto text/plain -- -- Реализует {{навигационная таблица}}, {{подгруппы навигационной таблицы}} и {{навигационная таблица с блоками}}. -- Основной объём кода заимствован из английского Module:Navbox. -- local p = {} local navbar = require('Module:Navbar')._ruwikiNavbar local getArgs -- lazily initialized local yesno -- lazily initialized local styleratio local ODD_EVEN_MARKER = '\127_ODDEVEN_\127' local RESTART_MARKER = '\127_ODDEVEN0_\127' local REGEX_MARKER = '\127_ODDEVEN(%d?)_\127' -- общие параметры для всех шаблонов local commonAliases = { name = {'name', 'имя'}, navigation = {'navigation', 'навигация'}, navbar = {'navbar', 'ссылка_на_просмотр'}, state = {'state'}, orphan = {'orphan'}, tracking = {'tracking'}, border = {'border', 1}, title = {'title', 'заголовок'}, titlegroup = {'titlegroup'}, above = {'above', 'вверху'}, image = {'image', 'изображение'}, imageleft = {'imageleft', 'изображение2', 'изображение_слева'}, below = {'below', 'внизу'}, bodyclass = {'bodyclass', 'класс_тела'}, titleclass = {'titleclass', 'класс_заголовка'}, titlegroupclass = {'titlegroupclass'}, aboveclass = {'aboveclass', 'класс_вверху'}, belowclass = {'belowclass', 'класс_внизу'}, groupclass = {'groupclass', 'класс_групп'}, listclass = {'listclass', 'класс_списков'}, imageclass = {'imageclass', 'класс_изображения'}, basestyle = {'basestyle', 'стиль', 'стиль_базовый'}, bodystyle = {'style', 'bodystyle', 'стиль_тела'}, titlestyle = {'titlestyle', 'стиль_основного_заголовка', 'стиль_заголовка'}, titlegroupstyle = {'titlegroupstyle'}, innerstyle = {'innerstyle'}, abovestyle = {'abovestyle', 'стиль_вверху'}, belowstyle = {'belowstyle', 'стиль_внизу'}, imagestyle = {'imagestyle', 'стиль_изображения'}, imageleftstyle = {'imageleftstyle', 'imagestyle2', 'стиль_изображения_слева'}, } -- параметры {{навигационная таблица}} и {{подгруппы навигационной таблицы}} local standardAliases = { groupstyle = {'groupstyle', 'стиль_заголовков', 'стиль_групп'}, liststyle = {'liststyle', 'стиль_списков'}, evenodd = {'evenodd', 'чётные_нечётные', 'четные_нечетные'}, groupwidth = {'groupwidth', 'ширина_групп'}, listpadding = {'listpadding', 'отступ_списков'}, } -- параметры {{навигационная таблица}} и {{подгруппы навигационной таблицы}} с нумерацией local standardElementAliases = { group = {'group%s', 'заголовок%s', 'группа%s'}, list = {'list%s', 'список%s'}, groupstyle = {'group%sstyle', 'стиль_заголовка%s', 'стиль_группы%s'}, listclass = {'list%sclass', 'класс%sсписка', 'класс_списка%s'}, liststyle = {'list%sstyle', 'стиль_списка%s'}, listpadding = {'list%spadding'} } -- параметры {{навигационная таблица с блоками}} -- с нижнего подчеркивания начинаются параметры, конфликтующие с standardAliases local groupsParentAliases = { selected = {'selected', 'открытый_блок', 'развернуть'}, secttitlestyle = {'secttitlestyle', 'стиль_заголовков'}, _groupstyle = {'groupstyle', 'стиль_блоков'}, _liststyle = {'liststyle', 'стиль_списков', 'contentstyle'}, _listpadding = {'listpadding', 'отступ_списка', 'отступ_списков'} } -- параметры {{навигационная таблица с блоками}} с нумерацией local groupsChildAliases = { groupname = {'abbr%s', 'имя_блока%s', 'аббр%s'}, state = {'state%s'}, title = {'group%s', 'блок%s', 'заголовок%s', 'группа%s', 'sect%s', 'section%s', 'секция%s'}, list1 = {'list%s', 'список%s', 'content%s'}, image = {'image%s', 'изображение%s'}, imageleft = {'imageleft%s', 'изображение_слева%s'}, secttitlestyle = {'sect%stitlestyle', 'стиль%sзаголовка', 'стиль_секции%s'}, groupstyle = {'group%sstyle', 'стиль%sблока', 'стиль_группы%s', 'стиль_блока%s'}, listclass = {'list%sclass', 'класс%sсписка', 'класс_списка%s'}, liststyle = {'list%sstyle', 'стиль%sсписка', 'стиль_списка%s', 'content%sstyle'}, color = {'цвет%s'} } local function checkAliases(args, aliases, index) for _, alias in ipairs(aliases) do local arg if index then arg = args[string.format(alias, index)] else arg = args[alias] end if arg then return arg end end return nil end local function checkElAliases(args, name, index) return checkAliases(args, standardElementAliases[name], index) end local function concatStyles(t) local res for k, v in pairs(t) do if v then res = res and res .. ';' .. v or v end end return res end local function striped(wikitext, args) -- Return wikitext with markers replaced for odd/even striping. -- Child (subgroup) navboxes are flagged with a category that is removed -- by parent navboxes. The result is that the category shows all pages -- where a child navbox is not contained in a parent navbox. local orphanCat = '[[Категория:Навигационные шаблоны без родителя]]' if args.border == 'subgroup' and args.orphan ~= 'yes' then -- No change; striping occurs in outermost navbox. return wikitext .. orphanCat end local first, second = 'odd', 'even' if args.evenodd then if args.evenodd == 'swap' then first, second = second, first else first = args.evenodd second = first end end local changer if first == second then changer = first else local index = 0 changer = function (code) if code == '0' then -- Current occurrence is for a group before a nested table. -- Set it to first as a valid although pointless class. -- The next occurrence will be the first row after a title -- in a subgroup and will also be first. index = 0 return first end index = index + 1 return index % 2 == 1 and first or second end end local regex = orphanCat:gsub('([%[%]])', '%%%1') return (wikitext:gsub(regex, ''):gsub(REGEX_MARKER, changer)) -- () omits gsub count end local function addNewline(s) if s:match('^[*:;#]') or s:match('^{|') then return '\n' .. s ..'\n' else return s end end local function renderNavBar(titleCell, args) local currentFrame = mw.getCurrentFrame() if args.navbar ~= 'off' and args.navbar ~= 'plain' and (args.name or not currentFrame:getParent():getTitle():gsub('/песочница$', '') == 'Шаблон:Навигационная таблица') then --- Gear creation titleCell :tag('span') :addClass('navbox-gear') :css('float', 'left') :css('text-align', 'left') :css('width', '5em') :css('margin-right', '0.5em') :wikitext(navbar{ args.name, ['fontstyle'] = args.titlestyle or args.basestyle }) end end -- -- Title row -- local function renderTitleRow(tbl, args) if not args.title then return end local titleRow = tbl:tag('tr') if args.titlegroup then titleRow :tag('th') :attr('scope', 'row') :addClass('navbox-group') :addClass(args.titlegroupclass) :cssText(args.basestyle) :cssText(args.groupstyle) :cssText(args.titlegroupstyle) :wikitext(args.titlegroup) end local titleCell = titleRow:tag('th'):attr('scope', 'colgroup') if args.titlegroup then titleCell :css('border-left', '2px solid #fdfdfd') :css('width', '100%') end local titleColspan = 2 if args.imageleft then titleColspan = titleColspan + 1 end if args.image then titleColspan = titleColspan + 1 end if args.titlegroup then titleColspan = titleColspan - 1 end titleCell :cssText(args.basestyle) :cssText(args.titlestyle) :addClass('navbox-title') :attr('colspan', titleColspan) renderNavBar(titleCell, args) titleCell :tag('div') :attr('id', mw.uri.anchorEncode(args.title)) :addClass(args.titleclass) :css('font-size', '114%') :css('margin', '0 5em') :wikitext(addNewline(args.title)) end -- -- Above/Below rows -- local function getAboveBelowColspan(args) local ret = 2 if args.imageleft then ret = ret + 1 end if args.image then ret = ret + 1 end return ret end local function renderAboveRow(tbl, args) if not args.above then return end tbl:tag('tr') :tag('td') :addClass('navbox-abovebelow') :addClass(args.aboveclass) :cssText(args.basestyle) :cssText(args.abovestyle) :attr('colspan', getAboveBelowColspan(args)) :tag('div') :wikitext(addNewline(args.above)) end local function renderBelowRow(tbl, args) if not args.below then return end tbl:tag('tr') :tag('td') :addClass('navbox-abovebelow') :addClass(args.belowclass) :cssText(args.basestyle) :cssText(args.belowstyle) :attr('colspan', getAboveBelowColspan(args)) :tag('div') :wikitext(addNewline(args.below)) end -- -- List rows -- local function haveSubgroups(args) for i = 1, 23 do if checkElAliases(args, 'group', i) and checkElAliases(args, 'list', i) then return true end end return false end local function renderListRow(tbl, args, index, rowspan, rowArgs) local row = tbl:tag('tr') if index == 1 and args.imageleft then row :tag('td') :addClass('navbox-image') :addClass(args.imageclass) :css('width', '1px') :css('padding', '0px 7px 0px 0px') :cssText(args.imageleftstyle) :attr('rowspan', rowspan) :tag('div') :wikitext(addNewline(args.imageleft)) end if rowArgs.group then local groupCell = row:tag('th') groupCell :attr('scope', 'row') :addClass('navbox-group') :addClass(args.groupclass) :cssText(args.basestyle) :css('width', args.groupwidth or '1px') -- If groupwidth not specified, minimize width groupCell :cssText(args.groupstyle) :cssText(rowArgs.groupstyle) :wikitext(rowArgs.group) end local listCell = row:tag('td') if rowArgs.group then listCell :css('text-align', 'left') :css('border-left-width', '2px') :css('border-left-style', 'solid') else if haveSubgroups(args) then listCell :attr('colspan', 2) end end if not args.groupwidth then listCell:css('width', '100%') end local listText = rowArgs.list local oddEven = ODD_EVEN_MARKER if listText:sub(1, 12) == '</div><table' then -- Assume list text is for a subgroup navbox so no automatic striping for this row. oddEven = listText:find('<th[^>]*"navbox%-title"') and RESTART_MARKER or 'odd' end listCell :css('padding', '0px') :cssText(args.liststyle) :cssText(rowArgs.liststyle) :addClass('navbox-list') :addClass('navbox-' .. oddEven) :addClass(args.listclass) :addClass(rowArgs.listclass) :tag('div') :css('padding', rowArgs.listpadding or args.listpadding or '0em 0.25em') :wikitext(addNewline(listText)) if index == 1 and args.image then row :tag('td') :addClass('navbox-image') :addClass(args.imageclass) :css('width', '1px') :css('padding', '0px 0px 0px 7px') :cssText(args.imagestyle) :attr('rowspan', rowspan) :tag('div') :wikitext(addNewline(args.image)) end end -- -- Tracking categories -- local function needsChangetoSubgroups(args) for i = 1, 23 do if (checkElAliases(args, 'group', i)) and not (checkElAliases(args, 'list', i)) then return true end end return false end local function needsHorizontalLists(args) if args.border == 'subgroup' or args.tracking == 'no' then return false end local listClasses = { ['plainlist'] = true, ['hlist'] = true, ['hlist hnum'] = true, ['hlist hwrap'] = true, ['hlist vcard'] = true, ['vcard hlist'] = true, ['hlist vevent'] = true, ['hlist hlist-items-nowrap'] = true, ['hlist-items-nowrap'] = true, } return not (listClasses[args.listclass] or listClasses[args.bodyclass]) end -- local function hasBackgroundColors() -- return mw.ustring.match(titlestyle or '','background') or mw.ustring.match(groupstyle or '','background') or mw.ustring.match(basestyle or '','background') -- end local function isIllegible(args) if not styleratio then styleratio = require('Module:Color contrast')._styleratio end for key, style in pairs(args) do if tostring(key):match("style$") or tostring(key):match("^стиль") then if styleratio{mw.text.unstripNoWiki(style)} < 4.5 then return true end end end return false end local function getTrackingCategories(args) local cats = {} if needsChangetoSubgroups(args) then table.insert(cats, 'Навигационные шаблоны с ошибочным использованием заголовков') end if needsHorizontalLists(args) then table.insert(cats, 'Навигационные шаблоны без горизонтальных списков') end if isIllegible(args) then table.insert(cats, 'Потенциально нечитаемые навигационные шаблоны') end return cats end local function renderTrackingCategories(builder, args) local title = mw.title.getCurrentTitle() if title.namespace ~= 10 then return end -- not in template space local subpage = title.subpageText if subpage == 'doc' or subpage == 'песочница' or subpage == 'тесты' then return end for i, cat in ipairs(getTrackingCategories(args)) do builder:wikitext('[[Категория:' .. cat .. ']]') end end -- -- Main navbox tables -- local function renderMainTable(args, listnums) local tbl = mw.html.create('table') :addClass('nowraplinks') :addClass(args.bodyclass) if args.title and (args.state ~= 'plain' and args.state ~= 'off') then tbl :addClass('collapsible') :addClass(args.state or 'autocollapse') end tbl:css('border-spacing', 0) if args.border == 'subgroup' or args.border == 'none' then tbl :addClass('navbox-subgroup') :cssText(args.bodystyle) else -- regular navbox - bodystyle and style will be applied to the wrapper table tbl :addClass('navbox-inner') :css('background', 'transparent') :css('color', 'inherit') end tbl:cssText(args.innerstyle) renderTitleRow(tbl, args) renderAboveRow(tbl, args) for i, listnum in ipairs(listnums) do local rowArgs = { group = checkElAliases(args, 'group', listnum), list = checkElAliases(args, 'list', listnum), groupstyle = checkElAliases(args, 'groupstyle', listnum), listclass = checkElAliases(args, 'listclass', listnum), liststyle = checkElAliases(args, 'liststyle', listnum), listpadding = checkElAliases(args, 'listpadding', listnum) } renderListRow(tbl, args, i, #listnums, rowArgs) end renderBelowRow(tbl, args) return tbl end -- Read the arguments in the order they'll be output in, to make references number in the right order. local function readInTheRightOrder(args, groupAliases, listAliases) local _ _ = checkAliases(args, commonAliases.title) _ = checkAliases(args, commonAliases.above) for i = 1, 23 do _ = checkAliases(args, groupAliases, i) _ = checkAliases(args, listAliases, i) end _ = checkAliases(args, commonAliases.below) end function p._navbox(args) if not yesno then yesno = require('Module:Yesno') end local listnums = {} for k, v in pairs(args) do local listnum = ('' .. k):match('^list(%d+)$') or ('' .. k):match('^список(%d+)$') if listnum then table.insert(listnums, tonumber(listnum)) end end table.sort(listnums) args.border = mw.text.trim(args.border or args[1] or '') if args.border == 'child' then args.border = 'subgroup' end for argname, aliasesList in pairs(commonAliases) do args[argname] = checkAliases(args, aliasesList) end for argname, aliasesList in pairs(standardAliases) do args[argname] = checkAliases(args, aliasesList) end args.navigation = yesno(args.navigation, '') -- render the main body of the navbox local tbl = renderMainTable(args, listnums) -- render the appropriate wrapper around the navbox, depending on the border param local res = mw.html.create() if args.border == 'none' then local nav = res:tag('div') :attr('role', 'navigation') :node(tbl) if args.title then nav:attr('aria-labelledby', mw.uri.anchorEncode(args.title)) else nav:attr('aria-label', 'Навигационный шаблон') end if args.name and args.name ~= '-' then nav:attr('data-name', args.name) end if args.navigation == true then nav:attr('data-navboxnavigation', '1') elseif args.navigation == false then nav:attr('data-navboxnavigation', '0') end elseif args.border == 'subgroup' then -- We assume that this navbox is being rendered in a list cell of a parent navbox, and is -- therefore inside a div with padding:0em 0.25em. We start with a </div> to avoid the -- padding being applied, and at the end add a <div> to balance out the parent's </div> res :wikitext('</div>') -- XXX: hack due to lack of unclosed support in mw.html. :node(tbl) :wikitext('<div>') -- XXX: hack due to lack of unclosed support in mw.html. else local nav = res:tag('div') :attr('role', 'navigation') :addClass('navbox') :cssText(args.bodystyle) :node(tbl) if args.title then nav:attr('aria-labelledby', mw.uri.anchorEncode(args.title)) else nav:attr('aria-label', 'Навигационный шаблон') end if args.name and args.name ~= '-' then nav:attr('data-name', args.name) end if args.navigation == true then nav:attr('data-navboxnavigation', '1') elseif args.navigation == false then nav:attr('data-navboxnavigation', '0') end end renderTrackingCategories(res, args) return striped(tostring(res), args) end function p.navbox(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end if not yesno then yesno = require('Module:Yesno') end args = getArgs(frame, {wrappers = {'Шаблон:Навигационная таблица', 'Шаблон:Подгруппы навигационной таблицы'}}) if frame.args.border then -- This allows Template:Navbox_subgroup to use {{#invoke:Navbox|navbox|border=...}}. args.border = frame.args.border end readInTheRightOrder(args, standardElementAliases.group, standardElementAliases.list) return p._navbox(args) end function p.navboxWithCollapsibleGroups(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end local args = getArgs(frame, {wrappers = {'Шаблон:Навигационная таблица с блоками'}}) readInTheRightOrder(args, groupsChildAliases.title, groupsChildAliases.list1) local parent = {} for argname, aliasesList in pairs(commonAliases) do parent[argname] = checkAliases(args, aliasesList) end for argname, aliasesList in pairs(groupsParentAliases) do parent[argname] = checkAliases(args, aliasesList) end for i = 1, 20 do local child = {} for argname, aliasesList in pairs(groupsChildAliases) do child[argname] = checkAliases(args, aliasesList, i) end child.color = child.color and string.format('background:%s;', child.color) or '' child.border = 'child' child.navbar = 'plain' if parent.selected and parent.selected == child.groupname then child.state = 'uncollapsed' end child.state = child.state or 'collapsed' child.basestyle = concatStyles{parent.basestyle, parent.secttitlestyle, child.secttitlestyle} child.titlestyle = concatStyles{parent._groupstyle, child.groupstyle, child.color} child.liststyle = concatStyles{parent._liststyle, child.liststyle} child.lispadding = parent._listpadding if child.title then parent['list' .. i] = p._navbox(child) else parent['list' .. i] = child.list1 end end return p._navbox(parent) end return p cf72974326d19e1d4d58d2d00766b944b3ca0944 Шаблон:TOC right/styles.css 10 195 436 2024-02-23T16:55:08Z ruwiki>Stjn 0 не отображать в новом Векторе sanitized-css text/css @media (min-width: 720px) { body:not(.skin-minerva) .ts-TOC_right { margin-left: 1em; margin-bottom: 0.5em; float: right; clear: right; } } @media (max-width: 719px) { .ts-TOC_right { width: auto !important; max-width: none !important; clear: none !important; } } body.skin-vector-2022 .ts-TOC_right { display: none; } /* [[Категория:Шаблоны:Подстраницы CSS]] */ 710a99f2d4d2a78eb7a6f884538055bb6ac67c99 Шаблон:Навигационная таблица 10 215 478 2024-02-26T11:53:15Z ruwiki>Stjn 0 тоже может иметь эти значения wikitext text/x-wiki <includeonly>{{#invoke:Navbox|navbox}}</includeonly>{{#ifeq: {{NAMESPACE}} | Шаблон | {{#switch: {{{1|{{{border|}}}}}} | child | subgroup | none = | {{#ifeq: {{{имя|{{{name|}}}}}} | {{PAGENAME}} | | {{#if:{{yesno|{{{tracking|}}}|no=1|yes=|blank=}} | | {{#if: {{{имя|{{{name|}}}}}} | {{#ifeq:{{ROOTPAGENAME}}|Работа недели||{{no-doc|[[Категория:Навигационные шаблоны, у которых нужно проверить параметр Имя]]}}}} | [[Категория:Навигационные шаблоны, у которых предположительно недостаёт параметра Имя]] }} }} }} }} }}<noinclude> {{doc}} </noinclude> b1c7f6e61d3b9cdd1daaf4d95e30e299a1d9eb5c Модуль:Delink 828 264 689 2024-02-28T16:27:08Z ruwiki>Dima st bk 0 sync with enwiki, see authors of this version https://en.wikipedia.org/w/index.php?title=Module:Delink&oldid=1208348327 Scribunto text/plain -- This module de-links most wikitext. require("strict") local yesno = require("Module:Yesno") local p = {} local getArgs local function delinkReversePipeTrick(s) if s:match("^%[%[|.*[|\n]") then -- Check for newlines or multiple pipes. return s end return s:match("%[%[|(.*)%]%]") end local function delinkPipeTrick(s) -- We need to deal with colons, brackets, and commas, per [[Help:Pipe trick]]. -- First, remove the text before the first colon, if any. if s:match(":") then s = s:match("%[%[.-:(.*)|%]%]") -- If there are no colons, grab all of the text apart from the square brackets and the pipe. else s = s:match("%[%[(.*)|%]%]") end -- Next up, brackets and commas. if s:match("%(.-%)$") then -- Brackets trump commas. s = s:match("(.-) ?%(.-%)$") elseif s:match(",") then -- If there are no brackets, display only the text before the first comma. s = s:match("(.-),.*$") end return s end -- Return wikilink target |wikilinks=target local function getDelinkedTarget(s) local result = s -- Deal with the reverse pipe trick. if result:match("%[%[|") then return delinkReversePipeTrick(result) end result = mw.uri.decode(result, "PATH") -- decode percent-encoded entities. Leave underscores and plus signs. result = mw.text.decode(result, true) -- decode HTML entities. -- Check for bad titles. To do this we need to find the -- title area of the link, i.e. the part before any pipes. local target_area if result:match("|") then -- Find if we're dealing with a piped link. target_area = result:match("^%[%[(.-)|.*%]%]") else target_area = result:match("^%[%[(.-)%]%]") end -- Check for bad characters. if mw.ustring.match(target_area, "[%[%]<>{}%%%c\n]") and mw.ustring.match(target_area, "[%[%]<>{}%%%c\n]") ~= "?" then return s end return target_area end local function getDelinkedLabel(s) local result = s -- Deal with the reverse pipe trick. if result:match("%[%[|") then return delinkReversePipeTrick(result) end result = mw.uri.decode(result, "PATH") -- decode percent-encoded entities. Leave underscores and plus signs. result = mw.text.decode(result, true) -- decode HTML entities. -- Check for bad titles. To do this we need to find the -- title area of the link, i.e. the part before any pipes. local target_area if result:match("|") then -- Find if we're dealing with a piped link. target_area = result:match("^%[%[(.-)|.*%]%]") else target_area = result:match("^%[%[(.-)%]%]") end -- Check for bad characters. if mw.ustring.match(target_area, "[%[%]<>{}%%%c\n]") and mw.ustring.match(target_area, "[%[%]<>{}%%%c\n]") ~= "?" then return s end -- Check for categories, interwikis, and files. local colon_prefix = result:match("%[%[(.-):.*%]%]") or "" -- Get the text before the first colon. local ns = mw.site.namespaces[colon_prefix] -- see if this is a known namespace if mw.language.isKnownLanguageTag(colon_prefix) or (ns and (ns.canonicalName == "File" or ns.canonicalName == "Category")) then return "" end -- Remove the colon if the link is using the [[Help:Colon trick]]. if result:match("%[%[:") then result = "[[" .. result:match("%[%[:(.*%]%])") end -- Deal with links using the [[Help:Pipe trick]]. if mw.ustring.match(result, "^%[%[[^|]*|%]%]") then return delinkPipeTrick(result) end -- Find the display area of the wikilink if result:match("|") then -- Find if we're dealing with a piped link. result = result:match("^%[%[.-|(.+)%]%]") -- Remove new lines from the display of multiline piped links, -- where the pipe is before the first new line. result = result:gsub("\n", "") else result = result:match("^%[%[(.-)%]%]") end return result end local function delinkURL(s) -- Assume we have already delinked internal wikilinks, and that -- we have been passed some text between two square brackets [foo]. -- If the text contains a line break it is not formatted as a URL, regardless of other content. if s:match("\n") then return s end -- Check if the text has a valid URL prefix and at least one valid URL character. local valid_url_prefixes = {"//", "http://", "https://", "ftp://", "gopher://", "mailto:", "news:", "irc://"} local url_prefix for _ ,v in ipairs(valid_url_prefixes) do if mw.ustring.match(s, '^%[' .. v ..'[^"%s].*%]' ) then url_prefix = v break end end -- Get display text if not url_prefix then return s end s = s:match("^%[" .. url_prefix .. "(.*)%]") -- Grab all of the text after the URL prefix and before the final square bracket. s = s:match('^.-(["<> ].*)') or "" -- Grab all of the text after the first URL separator character ("<> ). s = mw.ustring.match(s, "^%s*(%S.*)$") or "" -- If the separating character was a space, trim it off. local s_decoded = mw.text.decode(s, true) if mw.ustring.match(s_decoded, "%c") then return s end return s_decoded end local function delinkLinkClass(text, pattern, delinkFunction) if type(text) ~= "string" then error("Attempt to de-link non-string input.", 2) end if type(pattern) ~= "string" or mw.ustring.sub(pattern, 1, 1) ~= "^" then error('Invalid pattern detected. Patterns must begin with "^".', 2) end -- Iterate over the text string, and replace any matched text. using the -- delink function. We need to iterate character by character rather -- than just use gsub, otherwise nested links aren't detected properly. local result = "" while text ~= "" do -- Replace text using one iteration of gsub. text = mw.ustring.gsub(text, pattern, delinkFunction, 1) -- Append the left-most character to the result string. result = result .. mw.ustring.sub(text, 1, 1) text = mw.ustring.sub(text, 2, -1) end return result end function p._delink(args) local text = args[1] or "" if yesno(args.markers) == true then text = mw.text.killMarkers(text) -- [[Help:Strip markers]] end if yesno(args.refs) == true then -- Remove any [[Help:Strip markers]] representing ref tags. In most situations -- this is not a good idea - only use it if you know what you are doing! text = mw.ustring.gsub(text, "UNIQ%w*%-ref%-%d*%-QINU", "") end if not (yesno(args.comments) == false) then text = text:gsub("<!%-%-.-%-%->", "") -- Remove html comments. end if not (yesno(args.wikilinks) == false) and args.wikilinks ~= "target" then -- De-link wikilinks and return the label portion of the wikilink. text = delinkLinkClass(text, "^%[%[.-%]%]", getDelinkedLabel) elseif args.wikilinks == "target" then -- De-link wikilinks and return the target portions of the wikilink. text = delinkLinkClass(text, "^%[%[.-%]%]", getDelinkedTarget) end if not (yesno(args.urls) == false) then text = delinkLinkClass(text, "^%[.-%]", delinkURL) -- De-link URLs. end if not (yesno(args.whitespace) == false) then -- Replace single new lines with a single space, but leave double new lines -- and new lines only containing spaces or tabs before a second new line. text = mw.ustring.gsub(text, "([^\n \t][ \t]*)\n([ \t]*[^\n \t])", "%1 %2") text = text:gsub("[ \t]+", " ") -- Remove extra tabs and spaces. end return text end function p.delink(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end return p._delink(getArgs(frame, {wrappers = 'Template:Delink'})) end return p eb6cae0d369f288b0b1600633d9bf7874cefdcbc Модуль:Message box 828 21 136 2024-03-25T18:05:03Z ruwiki>Stjn 0 fix Scribunto text/plain -- This is a meta-module for producing message box templates, including -- {{mbox}}, {{ambox}}, {{imbox}}, {{tmbox}}, {{ombox}}, {{cmbox}} and {{fmbox}}. -- Load necessary modules. require('strict') local getArgs local categoryHandler = require('Module:Category handler')._main local yesno = require('Module:Yesno') local boxDate = require('Module:Calendar').bxDate; -- Get a language object for formatDate and ucfirst. local lang = mw.language.getContentLanguage() -- Define constants local CONFIG_MODULE = 'Module:Message box/configuration' -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function getTitleObject(...) -- Get the title object, passing the function through pcall -- in case we are over the expensive function count limit. local success, title = pcall(mw.title.new, ...) if success then return title end end local function union(t1, t2) -- Returns the union of two arrays. local vals = {} for i, v in ipairs(t1) do vals[v] = true end for i, v in ipairs(t2) do vals[v] = true end local ret = {} for k in pairs(vals) do table.insert(ret, k) end table.sort(ret) return ret end local function getArgNums(args, prefix) local nums = {} for k, v in pairs(args) do local num = mw.ustring.match(tostring(k), '^' .. prefix .. '([1-9]%d*)$') if num then table.insert(nums, tonumber(num)) end end table.sort(nums) return nums end -- локальная обёртка, игнорирует таблицу с номерами дня, месяца и года local function formatDate(txtDateIn, strFormat, params) local txtDateOut, date, status = boxDate(txtDateIn, strFormat, params) if status.brk then return error(status.errorText) else return txtDateOut end end -------------------------------------------------------------------------------- -- Box class definition -------------------------------------------------------------------------------- local MessageBox = {} MessageBox.__index = MessageBox function MessageBox.new(boxType, args, cfg) args = args or {} local obj = {} -- Set the title object and the namespace. obj.title = getTitleObject(args.page) or mw.title.getCurrentTitle() -- Set the config for our box type. obj.cfg = cfg[boxType] if not obj.cfg then local ns = obj.title.namespace -- boxType is "mbox" or invalid input if ns == 0 then obj.cfg = cfg.ambox -- main namespace elseif ns == 6 then obj.cfg = cfg.imbox -- file namespace elseif ns == 14 then obj.cfg = cfg.cmbox -- category namespace else local nsTable = mw.site.namespaces[ns] if nsTable and nsTable.isTalk then obj.cfg = cfg.tmbox -- any talk namespace else obj.cfg = cfg.ombox -- other namespaces or invalid input end end end -- Set the arguments, and remove all blank arguments except for the ones -- listed in cfg.allowBlankParams. do local newArgs = {} for k, v in pairs(args) do if v ~= '' then newArgs[k] = v end end for i, param in ipairs(obj.cfg.allowBlankParams or {}) do newArgs[param] = args[param] end obj.args = newArgs end -- Define internal data structure. obj.categories = {} obj.classes = {} return setmetatable(obj, MessageBox) end function MessageBox:addCat(ns, cat, sort) if not cat then return nil end if sort then cat = string.format('[[Категория:%s|%s]]', cat, sort) else cat = string.format('[[Категория:%s]]', cat) end self.categories[ns] = self.categories[ns] or {} table.insert(self.categories[ns], cat) end function MessageBox:addClass(class) if not class then return nil end table.insert(self.classes, class) end function MessageBox:setParameters() local args = self.args local cfg = self.cfg -- Get type data. self.type = args.type local typeData = cfg.types[self.type] self.invalidTypeError = cfg.showInvalidTypeError and self.type and not typeData typeData = typeData or cfg.types[cfg.default] self.typeClass = typeData.class self.typeImage = typeData.image -- Find if the box has been wrongly substituted. self.isSubstituted = cfg.substCheck and args.subst == 'SUBST' -- Find whether we are using a small message box. self.isSmall = cfg.allowSmall and ( cfg.smallParam and args.small == cfg.smallParam or not cfg.smallParam and yesno(args.small) ) -- Add attributes, classes and styles. self.id = args.id self.name = args.name if self.name then self:addClass('mbox-' .. string.gsub(self.name,' ','_')) end if yesno(args.plainlinks) ~= false then self:addClass('plainlinks') end for _, class in ipairs(cfg.classes or {}) do self:addClass(class) end if self.isSmall then self:addClass(cfg.smallClass or 'mbox-small') end self:addClass(self.typeClass) self:addClass(args.class) self.style = args.style self.attrs = args.attrs self.dataLabel1 = args['data-label-1'] self.dataLabel2 = args['data-label-2'] self.dataLabel3 = args['data-label-3'] self.dataValue1 = args['data-value-1'] self.dataValue2 = args['data-value-2'] self.dataValue3 = args['data-value-3'] -- Set text style. self.textstyle = args.textstyle -- Find if we are on the template page or not. This functionality is only -- used if useCollapsibleTextFields is set, or if both cfg.templateCategory -- and cfg.templateCategoryRequireName are set. self.useCollapsibleTextFields = cfg.useCollapsibleTextFields if self.useCollapsibleTextFields or cfg.templateCategory and cfg.templateCategoryRequireName then self.name = args.name if self.name then local templateName = mw.ustring.match( self.name, '^[tT][eE][mM][pP][lL][aA][tT][eE][%s_]*:[%s_]*(.*)$' ) or self.name templateName = ('Template:' .. templateName) or ('Шаблон:' .. templateName) self.templateTitle = getTitleObject(templateName) end self.isTemplatePage = self.templateTitle and mw.title.equals(self.title, self.templateTitle) end -- Process data for collapsible text fields. At the moment these are only -- used in {{ambox}}. if self.useCollapsibleTextFields then -- Get the self.issue value. if self.isSmall and args.smalltext then self.issue = args.smalltext else if args.sect and args.sect ~= '' or nil then local issue_sect = args.issue_sect issue_sect = type(issue_sect) == 'string' and issue_sect ~= '' and issue_sect or nil local text_sect = args.text_sect text_sect = type(text_sect) == 'string' and text_sect ~= '' and text_sect or nil local issues = {} table.insert(issues, issue_sect) table.insert(issues, text_sect) self.issue = table.concat(issues, ' ') else local issue = args.issue issue = type(issue) == 'string' and issue ~= '' and issue or nil local text = args.text text = type(text) == 'string' and text or nil local issues = {} table.insert(issues, issue) table.insert(issues, text) self.issue = table.concat(issues, ' ') end end -- Get the self.talk value. local talk = args.talk -- Show talk links on the template page or template subpages if the talk -- parameter is blank. if talk == '' and self.templateTitle and ( mw.title.equals(self.templateTitle, self.title) or self.title:isSubpageOf(self.templateTitle) ) then talk = '#' elseif talk == '' then talk = nil end if talk then -- If the talk value is a talk page, make a link to that page. Else -- assume that it's a section heading, and make a link to the talk -- page of the current page with that section heading. local talkTitle = getTitleObject(talk) local talkArgIsTalkPage = true if not talkTitle or not talkTitle.isTalkPage then talkArgIsTalkPage = false talkTitle = getTitleObject( self.title.text, mw.site.namespaces[self.title.namespace].talk.id ) end if talkTitle and talkTitle.exists then local talkText = 'Соответствующую дискуссию можно найти на' if talkArgIsTalkPage then talkText = string.format( '%s [[%s|%s]].', talkText, talk, talkTitle.prefixedText ) else talkText = string.format( '%s [[%s#%s|странице обсуждения]].', talkText, talkTitle.prefixedText, talk ) end self.talk = talkText end end -- Get other values. self.fix = args.fix ~= '' and args.fix or nil local date if args.date and args.date ~= '' then local status, result = pcall(formatDate, args.date) if status then date = string.format("(<span class='date'>%s</span>)", result) else date = string.format("<span class='error'>(Строка «%s» не является верной датой, пожалуйста, укажите дату в формате <code>ГГГГ-ММ-ДД</code>)</span>", args.date) end elseif args.date == '' and self.isTemplatePage then date = string.format("(<span class='date'>%s</span>)", formatDate( lang:formatDate('Y-m-d') ) ) -- тут возникновения ошибки, связанной с пользовательским вводом, не будет end if date then self.date = string.format(" <span class='mbox-date'>''%s''</span>", date) end self.info = args.info if yesno(args.removalnotice) then self.removalNotice = cfg.removalNotice end if args.shortFix then self.shortFix = args.shortFix end end -- Set the non-collapsible text field. At the moment this is used by all box -- types other than ambox, and also by ambox when small=yes. if self.isSmall then self.text = args.smalltext or args.text else self.text = args.text self.textsmall = args['text-small'] end -- Set the below row. self.below = cfg.below and args.below -- General image settings. self.imageCellDiv = not self.isSmall and cfg.imageCellDiv self.imageEmptyCell = cfg.imageEmptyCell if cfg.imageEmptyCellStyle then self.imageEmptyCellStyle = 'border:none;padding:0px;width:1px' end -- Left image settings. local imageLeft = self.isSmall and args.smallimage or args.image if cfg.imageCheckBlank and imageLeft ~= 'blank' and imageLeft ~= 'none' and imageLeft ~= '' or not cfg.imageCheckBlank and imageLeft ~= 'none' then self.imageLeft = imageLeft if not imageLeft then local imageSize = self.isSmall and (cfg.imageSmallSize or '30x30px') or cfg.imageSize or '40x40px' self.imageLeft = string.format('[[File:%s|%s|alt=]]', self.typeImage or 'Information icon4.svg', imageSize) end end -- Right image settings. local imageRight = self.isSmall and args.smallimageright or args.imageright if not (cfg.imageRightNone and imageRight == 'none') then self.imageRight = imageRight end -- set templatestyles self.base_templatestyles = cfg.templatestyles end function MessageBox:setMainspaceCategories() local args = self.args local cfg = self.cfg local date = nil if not cfg.allowMainspaceCategories then return nil end local nums = {} for _, prefix in ipairs{'cat', 'category', 'all'} do args[prefix .. '1'] = args[prefix] nums = union(nums, getArgNums(args, prefix)) end -- The following is roughly equivalent to the old {{Ambox/category}}. local status, result = pcall(formatDate, args.date, 'xg Y') if status then date = result end date = type(date) == 'string' and date local preposition = 'с' local suffix = 'года' for _, num in ipairs(nums) do local mainCat = args['cat' .. tostring(num)] or args['category' .. tostring(num)] local allCat = args['all' .. tostring(num)] mainCat = type(mainCat) == 'string' and mainCat allCat = type(allCat) == 'string' and allCat if mainCat and date and date ~= '' then local catTitle = string.format('%s %s %s %s', mainCat, preposition, date, suffix) self:addCat(0, catTitle) catTitle = getTitleObject('Категория:' .. catTitle) local status, result = pcall(formatDate, args.date) if not status then self:addCat(0, 'Википедия:Статьи с недопустимым параметром даты в шаблоне-сообщении') end elseif mainCat and (not date or date == '') then self:addCat(0, mainCat) end if allCat then self:addCat(0, allCat) end end end function MessageBox:setTemplateCategories() local args = self.args local cfg = self.cfg -- Add template categories. if cfg.templateCategory then if cfg.templateCategoryRequireName then if self.isTemplatePage then self:addCat(10, cfg.templateCategory) end elseif not self.title.isSubpage then self:addCat(10, cfg.templateCategory) end end -- Add template error categories. if cfg.templateErrorCategory then local templateErrorCategory = cfg.templateErrorCategory local templateCat, templateSort if not self.name and not self.title.isSubpage then templateCat = templateErrorCategory elseif self.isTemplatePage then local paramsToCheck = cfg.templateErrorParamsToCheck or {} local count = 0 for i, param in ipairs(paramsToCheck) do if not args[param] then count = count + 1 end end if count > 0 then templateCat = templateErrorCategory templateSort = tostring(count) end if self.categoryNums and #self.categoryNums > 0 then templateCat = templateErrorCategory templateSort = 'C' end end self:addCat(10, templateCat, templateSort) end end function MessageBox:setAllNamespaceCategories() -- Set categories for all namespaces. if self.invalidTypeError then local allSort = (self.title.namespace == 0 and 'Main:' or '') .. self.title.prefixedText self:addCat('all', 'Википедия:Необходимо исправить параметр в шаблоне-сообщении', allSort) end if self.isSubstituted then self:addCat('all', 'Википедия:Страницы с ошибочно подставленными шаблонами') end if self.isSmall then self:addCat(0, 'Википедия:Страницы с малыми шаблонами-сообщениями') end end function MessageBox:setCategories() if self.title.namespace == 0 then self:setMainspaceCategories() elseif self.title.namespace == 10 then self:setTemplateCategories() end self:setAllNamespaceCategories() end function MessageBox:renderCategories() -- Convert category tables to strings and pass them through -- [[Module:Category handler]]. return categoryHandler{ main = table.concat(self.categories[0] or {}), template = table.concat(self.categories[10] or {}), all = table.concat(self.categories.all or {}), nocat = self.args.nocat, page = self.args.page } end function MessageBox:export() local root = mw.html.create() -- Add the subst check error. if self.isSubstituted and self.name then root:tag('b') :addClass('error') :wikitext(string.format( 'Шаблон <code>%s[[Шаблон:%s|%s]]%s</code> был неккоректно подставлен.', mw.text.nowiki('{{'), self.name, self.name, mw.text.nowiki('}}') )) end -- Conditional TemplateStyles loading if self.base_templatestyles then local frame = mw.getCurrentFrame() root:wikitext(frame:extensionTag{ name = 'templatestyles', args = { src = self.base_templatestyles }, }) end -- Create the box table. local boxTable = root:tag('table') boxTable:attr('id', self.id or nil) for i, class in ipairs(self.classes or {}) do boxTable:addClass(class or nil) end boxTable :cssText(self.style or nil) :attr('role', 'presentation') if self.dataLabel1 then boxTable:attr('data-' .. self.dataLabel1, self.dataValue1) end if self.dataLabel2 then boxTable:attr('data-' .. self.dataLabel2, self.dataValue2) end if self.dataLabel3 then boxTable:attr('data-' .. self.dataLabel3, self.dataValue3) end if self.attrs then boxTable:attr(self.attrs) end -- Add the left-hand image. local row = boxTable:tag('tr') if self.imageLeft then local imageLeftCell = row:tag('td'):addClass('mbox-image') if self.imageCellDiv then -- If we are using a div, redefine imageLeftCell so that the image -- is inside it. Divs use style="width: 52px;", which limits the -- image width to 52px. If any images in a div are wider than that, -- they may overlap with the text or cause other display problems. imageLeftCell = imageLeftCell:tag('div'):css('width', '52px') end imageLeftCell:wikitext(self.imageLeft or nil) elseif self.imageEmptyCell then -- Some message boxes define an empty cell if no image is specified, and -- some don't. The old template code in templates where empty cells are -- specified gives the following hint: "No image. Cell with some width -- or padding necessary for text cell to have 100% width." row:tag('td') :addClass('mbox-empty-cell') :cssText(self.imageEmptyCellStyle or nil) end -- Add the text. local textCell = row:tag('td'):addClass('mbox-text') if self.useCollapsibleTextFields then -- The message box uses advanced text parameters that allow things to be -- collapsible. At the moment, only ambox uses this. textCell:cssText(self.textstyle or nil) local textCellDiv = textCell:tag('div') textCellDiv :addClass('mbox-text-div') :wikitext(self.issue or nil) local textsmallCellDiv = textCell:tag('div') textsmallCellDiv :addClass('mbox-textsmall-div hide-when-compact') :cssText(self.textsmallstyle) :wikitext(self.textsmall or nil) if (self.talk or self.fix) and not self.isSmall then textsmallCellDiv:tag('span') :addClass('hide-when-compact') :wikitext(self.fix and (' ' .. self.fix) or nil) :wikitext(self.talk and (' ' .. self.talk) or nil) end if self.textsmall or self.fix or self.talk then textsmallCellDiv:wikitext(self.date and (' ' .. self.date) or nil) else textCellDiv:wikitext(self.date and (' ' .. self.date) or nil) end if self.info and not self.isSmall then textsmallCellDiv :tag('span') :addClass('hide-when-compact') :wikitext(self.info and (' ' .. self.info) or nil) end if self.removalNotice then textsmallCellDiv:tag('small') :addClass('hide-when-compact') :tag('i') :wikitext(string.format(" (%s)", self.removalNotice)) end if self.shortFix then textCell:tag('div') :addClass('mbox-multiply') :tag('span') :wikitext(string.format("%s", self.shortFix)) :tag('span') :wikitext(self.date and (' ' .. self.date) or nil) end else -- Default text formatting - anything goes. textCell :cssText(self.textstyle or nil) :wikitext(self.text or nil) end -- Add the right-hand image. if self.imageRight then local imageRightCell = row:tag('td'):addClass('mbox-imageright') if self.imageCellDiv then -- If we are using a div, redefine imageRightCell so that the image -- is inside it. imageRightCell = imageRightCell:tag('div'):css('width', '52px') end imageRightCell :wikitext(self.imageRight or nil) end -- Add the below row. if self.below then boxTable:tag('tr') :tag('td') :attr('colspan', self.imageRight and '3' or '2') :addClass('mbox-text') :cssText(self.textstyle or nil) :wikitext(self.below or nil) end -- Add error message for invalid type parameters. if self.invalidTypeError then root:tag('div') :css('text-align', 'center') :wikitext(string.format( 'Этот шаблон-сообщение использует неверный параметр "type=%s", необходимо исправить.', self.type or '' )) end -- Add categories. root:wikitext(self:renderCategories() or nil) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p, mt = {}, {} function p._exportClasses() -- For testing. return { MessageBox = MessageBox } end function p.main(boxType, args, cfgTables) local box = MessageBox.new(boxType, args, cfgTables or mw.loadData(CONFIG_MODULE)) box:setParameters() box:setCategories() return box:export() end function mt.__index(t, k) return function (frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end return t.main(k, getArgs(frame, {trim = false, removeBlanks = false})) end end return setmetatable(p, mt) f2539b657a9cdadde7c0dd5ad270d3095b2bdd54 Шаблон:Очистить кэш 10 179 400 2024-03-27T11:58:48Z ruwiki>Stjn 0 не помещать на все страницы ежедневную очистку кэша wikitext text/x-wiki <!-- Класс purgelink и атрибут data-pagename используются в [[MediaWiki:Common.js]], чтобы очищать кэш без перехода на отдельную страницу --><span class="noprint purgelink" {{#if: {{{2|}}} | data-pagename="{{{2}}}" }}>{{выполнить скрипт|purgeLink}}[[Special:Purge/{{#if: {{{2|}}} | {{{2}}} | {{FULLPAGENAME}} }}|{{#if: {{{1|}}} | {{{1}}} | Очистить кэш }}]]</span>{{#ifeq: {{NAMESPACE}}{{{nocat|}}} | {{ns:10}} <!-- Шаблон --> | {{очищать кэш|ежедневно}} }}<noinclude>{{doc}}</noinclude> be6695060ca61d2125386d02d3a19109c0e7c27b Модуль:Yesno 828 127 296 2024-03-30T22:30:54Z ruwiki>Stjn 0 кириллическая у из-за невозможности различить от латинской Scribunto text/plain -- Function allowing for consistent treatment of boolean-like wikitext input. -- It works similarly to the template {{yesno}}. return function (val, default) -- If your wiki uses non-ascii characters for any of "yes", "no", etc., you -- should replace "val:lower()" with "mw.ustring.lower(val)" in the -- following line. val = type(val) == 'string' and val:lower() or val if val == nil then return nil elseif val == true or val == 'yes' or val == 'y' or val == 'true' or val == 't' or val == 'да' or val == 'д' -- кириллица or val == 'у' or val == '+' or tonumber(val) == 1 then return true elseif val == false or val == 'no' or val == 'n' or val == 'false' or val == 'f' or val == 'нет' or val == 'н' or val == '-' or tonumber(val) == 0 then return false else return default end end ae94e12a838e770797317ed07b57b330ffeb7658 Шаблон:Yesno-yes 10 153 348 2024-04-05T13:04:36Z ruwiki>Stjn 0 подстановка wikitext text/x-wiki {{safesubst:<noinclude />yesno|{{{1}}}|yes={{{yes|yes}}}|no={{{no|no}}}|blank={{{blank|yes}}}|¬={{{¬|yes}}}|def={{{def|yes}}}}}<noinclude> {{doc}} </noinclude> 3792ff694708f98102e3a6d556abe73bedc29069 Шаблон:Выполнить скрипт 10 182 406 2024-04-07T13:34:28Z ruwiki>Stjn 0 отключение старой схемы wikitext text/x-wiki {{#switch: {{{1|}}} | = | mainPage = [[Категория:Википедия:Заглавная страница|{{NAMESPACENUMBER}}]] | #default = {{#ifexist: Категория:Википедия:Страницы с гаджетом по требованию {{{1}}} | [[Категория:Википедия:Страницы с гаджетом по требованию {{{1}}}|{{NAMESPACENUMBER}}]] }} }}<noinclude> {{doc}} </noinclude> 6979ea0342067dc76b9adcb9a5e072207c2c5a63 Шаблон:СИШ 10 207 462 2024-04-07T23:07:09Z ruwiki>Stjn 0 режет глаз wikitext text/x-wiki <noinclude>{{к объединению|2020-11-10|Шаблон:High-use}} </noinclude>{{ombox |type = notice |image = [[Файл:Stalewarning.svg|40px|alt=Время]] |text = '''Внимание! Это один из [[Special:MostLinkedTemplates|самых используемых {{#ifeq: {{NAMESPACENUMBER}} | 828 | модулей | шаблонов }}]].''' |text-small = Каждое его изменение создаёт [[mw:Manual:Job queue/ru|дополнительную нагрузку]] на сервера проекта. Пожалуйста, убедитесь в адекватности и правильности ваших изменений, проверьте их на тестовых страницах.<br>[https://templatecount.toolforge.org/index.php?lang=ru&name={{PAGENAMEE}}&namespace={{NAMESPACENUMBER}} Узнать число включений]. }}<includeonly>{{no-doc|nocat={{{nocat|}}}|[[Категория:Шаблоны:С более чем 100 тысячами использований]]}}</includeonly><noinclude> {{doc}} </noinclude> 013201ef8d4ba8e3d1eb0dbba9c331a3d4ae519b Шаблон:High-use 10 220 488 2024-04-08T04:49:44Z ruwiki>MBH 0 [[у:Землеройкин/remove.js|Удалятор]]: номинация [[ВП:к удалению/8 апреля 2024#Шаблон:High-use]] wikitext text/x-wiki <noinclude>{{к удалению|2024-04-08}} </noinclude><noinclude>{{к объединению|2020-11-10|Шаблон:СИШ}}</noinclude>{{ombox | type = style | image = [[File:OOjs UI icon alert-yellow.svg|40px|alt=|link=]] | text = Этот {{#switch: {{NAMESPACE}} | Модуль = модуль | #default = шаблон }} используется на многих страницах, поэтому изменения в нём будут заметны многим. Пожалуйста, протестируйте любые изменения в песочнице или на вашей личной подстранице. Рассмотрите возможность обсуждения изменений на [[{{#switch: {{SUBPAGENAME}} | doc | sandbox = {{TALKSPACE}}:{{BASEPAGENAME}} | #default = {{TALKPAGENAME}} }}|странице обсуждения]] или [[ВП:Форум|форуме]] перед их внесением.<br>[https://templatecount.toolforge.org/index.php?lang=ru&name={{PAGENAMEE}}&namespace={{NAMESPACENUMBER}} Узнать число включений]. }}<includeonly>{{no-doc|nocat={{{nocat|}}}| [[Категория:Шаблоны:Критические]] }}</includeonly><noinclude>{{doc}}</noinclude> ded73fd2acfa6bc0f9f309d7d66181c33a520198 Модуль:UnitTests 828 206 460 2024-04-08T16:59:24Z ruwiki>Vavilexxx 0 уточнение Scribunto text/plain -- Модуль основан на коде модуля [[:en:Module:UnitTests|Module:UnitTests]] англоязычного раздела Википедии. -- UnitTester provides unit testing for other Lua scripts. For details see [[Wikipedia:Lua#Unit_testing]]. -- For user documentation see talk page. local UnitTester = {} local frame, tick, cross, should_highlight local result_table_header = '{|class="wikitable unit-tests-result"\n|+ %s\n' .. '! scope="col" | \n' .. '! scope="col" | Тест\n' .. '! scope="col" | Ожидаемое значение\n' .. '! scope="col" | Фактическое значение ' local result_table_live_sandbox_header = '{|class="wikitable unit-tests-result"\n|+ %s\n' .. '! scope="col" | \n' .. '! scope="col" | Тест\n' .. '! scope="col" | Фактическое значение\n' .. '! scope="col" | Песочница\n' .. '! scope="col" | Ожидаемое значение' local result_table = { n = 0 } local result_table_mt = { insert = function (self, ...) local n = self.n for i = 1, select('#', ...) do local val = select(i, ...) if val ~= nil then n = n + 1 self[n] = val end end self.n = n end, insert_format = function (self, ...) self:insert(string.format(...)) end, concat = table.concat } result_table_mt.__index = result_table_mt setmetatable(result_table, result_table_mt) local num_failures = 0 local num_runs = 0 local function first_difference(s1, s2) s1, s2 = tostring(s1), tostring(s2) if s1 == s2 then return '' end local max = math.min(#s1, #s2) for i = 1, max do if s1:sub(i,i) ~= s2:sub(i,i) then return i end end return max + 1 end local function return_varargs(...) return ... end function UnitTester:calculate_output(text, expected, actual, options) -- Set up some variables for throughout for ease num_runs = num_runs + 1 local options = options or {} -- Fix any stripmarkers if asked to do so to prevent incorrect fails local compared_expected = expected local compared_actual = actual if options.templatestyles then local pattern = '(\127[^\127]*UNIQ%-%-templatestyles%-)(%x+)(%-QINU[^\127]*\127)' local _, expected_stripmarker_id = compared_expected:match(pattern) -- when module rendering has templatestyles strip markers, use ID from expected to prevent false test fail if expected_stripmarker_id then compared_actual = compared_actual:gsub(pattern, '%1' .. expected_stripmarker_id .. '%3') -- replace actual id with expected id; ignore second capture in pattern compared_expected = compared_expected:gsub(pattern, '%1' .. expected_stripmarker_id .. '%3') -- account for other strip markers end end if options.stripmarker then local pattern = '(\127[^\127]*UNIQ%-%-%l+%-)(%x+)(%-%-?QINU[^\127]*\127)' local _, expected_stripmarker_id = compared_expected:match(pattern) if expected_stripmarker_id then compared_actual = compared_actual:gsub(pattern, '%1' .. expected_stripmarker_id .. '%3') compared_expected = compared_expected:gsub(pattern, '%1' .. expected_stripmarker_id .. '%3') end end -- Perform the comparison local success = compared_actual == compared_expected if not success then num_failures = num_failures + 1 end -- Sort the wikitext for displaying the results if options.combined then -- We need 2 rows available for the expected and actual columns -- Top one is parsed, bottom is unparsed local differs_at = self.differs_at and (' \n| rowspan=2|' .. first_difference(compared_expected, compared_actual)) or '' -- Local copies of tick/cross to allow for highlighting local highlight = (should_highlight and not success and 'style="background:#fc0;" ') or '' result_table:insert( -- Start output '| ', highlight, 'rowspan=2|', success and tick or cross, -- Tick/Cross (2 rows) ' \n| rowspan=2|', mw.text.nowiki(text), ' \n| ', -- Text used for the test (2 rows) expected, ' \n| ', actual, -- The parsed outputs (in the 1st row) differs_at, ' \n|-\n| ', -- Where any relevant difference was (2 rows) mw.text.nowiki(expected), ' \n| ', mw.text.nowiki(actual), -- The unparsed outputs (in the 2nd row) '\n|-\n' -- End output ) else -- Display normally with whichever option was preferred (nowiki/parsed) local differs_at = self.differs_at and (' \n| ' .. first_difference(compared_expected, compared_actual)) or '' local formatting = options.nowiki and mw.text.nowiki or return_varargs local highlight = (should_highlight and not success and 'style="background:#fc0;"|') or '' result_table:insert( -- Start output '| ', highlight, success and tick or cross, -- Tick/Cross ' \n| ', mw.text.nowiki(text), ' \n| ', -- Text used for the test formatting(expected), ' \n| ', formatting(actual), -- The formatted outputs differs_at, -- Where any relevant difference was '\n|-\n' -- End output ) end end function UnitTester:preprocess_equals(text, expected, options) local actual = frame:preprocess(text) self:calculate_output(text, expected, actual, options) end function UnitTester:preprocess_equals_many(prefix, suffix, cases, options) for _, case in ipairs(cases) do self:preprocess_equals(prefix .. case[1] .. suffix, case[2], options) end end function UnitTester:preprocess_equals_preprocess(text1, text2, options) local actual = frame:preprocess(text1) local expected = frame:preprocess(text2) self:calculate_output(text1, expected, actual, options) end function UnitTester:preprocess_equals_compare(live, sandbox, expected, options) local live_text = frame:preprocess(live) local sandbox_text = frame:preprocess(sandbox) local highlight_live = false local highlight_sandbox = false num_runs = num_runs + 1 if live_text == expected and sandbox_text == expected then result_table:insert('| ', tick) else result_table:insert('| ', cross) num_failures = num_failures + 1 if live_text ~= expected then highlight_live = true end if sandbox_text ~= expected then highlight_sandbox = true end end local formatting = (options and options.nowiki and mw.text.nowiki) or return_varargs local differs_at = self.differs_at and (' \n| ' .. first_difference(expected, live_text) or first_difference(expected, sandbox_text)) or '' result_table:insert( ' \n| ', mw.text.nowiki(live), should_highlight and highlight_live and ' \n|style="background: #fc0;"| ' or ' \n| ', formatting(live_text), should_highlight and highlight_sandbox and ' \n|style="background: #fc0;"| ' or ' \n| ', formatting(sandbox_text), ' \n| ', formatting(expected), differs_at, "\n|-\n" ) end function UnitTester:preprocess_equals_preprocess_many(prefix1, suffix1, prefix2, suffix2, cases, options) for _, case in ipairs(cases) do self:preprocess_equals_preprocess(prefix1 .. case[1] .. suffix1, prefix2 .. (case[2] and case[2] or case[1]) .. suffix2, options) end end function UnitTester:preprocess_equals_sandbox_many(module, function_name, cases, options) for _, case in ipairs(cases) do local live = module .. "|" .. function_name .. "|" .. case[1] .. "}}" local sandbox = module .. "/песочница|" .. function_name .. "|" .. case[1] .. "}}" self:preprocess_equals_compare(live, sandbox, case[2], options) end end function UnitTester:equals(name, actual, expected, options) num_runs = num_runs + 1 if actual == expected then result_table:insert('| ', tick) else result_table:insert('| ', cross) num_failures = num_failures + 1 end local formatting = (options and options.nowiki and mw.text.nowiki) or return_varargs local differs_at = self.differs_at and (' \n| ' .. first_difference(expected, actual)) or '' local display = options and options.display or return_varargs result_table:insert(' \n| ', name, ' \n| ', formatting(tostring(display(expected))), ' \n| ', formatting(tostring(display(actual))), differs_at, "\n|-\n") end local function deep_compare(t1, t2, ignore_mt) local ty1 = type(t1) local ty2 = type(t2) if ty1 ~= ty2 then return false end if ty1 ~= 'table' and ty2 ~= 'table' then return t1 == t2 end local mt = getmetatable(t1) if not ignore_mt and mt and mt.__eq then return t1 == t2 end for k1, v1 in pairs(t1) do local v2 = t2[k1] if v2 == nil or not deep_compare(v1, v2) then return false end end for k2, v2 in pairs(t2) do local v1 = t1[k2] if v1 == nil or not deep_compare(v1, v2) then return false end end return true end local function val_to_str(obj) local function table_key_to_str(k) if type(k) == 'string' and mw.ustring.match(k, '^[_%a][_%a%d]*$') then return k else return '[' .. val_to_str(k) .. ']' end end if type(obj) == "string" then obj = mw.ustring.gsub(obj, "\n", "\\n") if mw.ustring.match(mw.ustring.gsub(obj, '[^\'"]', ''), '^"+$') then return "'" .. obj .. "'" end return '"' .. mw.ustring.gsub(obj, '"', '\\"' ) .. '"' elseif type(obj) == "table" then local result, checked = {}, {} for k, v in ipairs(obj) do table.insert(result, val_to_str(v)) checked[k] = true end for k, v in pairs(obj) do if not checked[k] then table.insert(result, table_key_to_str(k) .. '=' .. val_to_str(v)) end end return '{' .. table.concat(result, ',') .. '}' else return tostring(obj) end end function UnitTester:equals_deep(name, actual, expected, options) num_runs = num_runs + 1 if deep_compare(actual, expected) then result_table:insert('| ', tick) else result_table:insert('| ', cross) num_failures = num_failures + 1 end local formatting = (options and options.nowiki and mw.text.nowiki) or return_varargs local actual_str = val_to_str(actual) local expected_str = val_to_str(expected) local differs_at = self.differs_at and (' \n| ' .. first_difference(expected_str, actual_str)) or '' result_table:insert(' \n| ', name, ' \n| ', formatting(expected_str), ' \n| ', formatting(actual_str), differs_at, "\n|-\n") end function UnitTester:iterate(examples, func) require 'libraryUtil'.checkType('iterate', 1, examples, 'table') if type(func) == 'string' then func = self[func] elseif type(func) ~= 'function' then error(("bad argument #2 to 'iterate' (expected function or string, got %s)") :format(type(func)), 2) end for i, example in ipairs(examples) do if type(example) == 'table' then func(self, unpack(example)) elseif type(example) == 'string' then self:heading(example) else error(('bad example #%d (expected table, got %s)') :format(i, type(example)), 2) end end end function UnitTester:heading(text) result_table:insert_format(' ! colspan="%u" style="text-align: left" | %s \n |- \n ', self.columns, text) end function UnitTester:run(frame_arg) frame = frame_arg self.frame = frame self.differs_at = frame.args['differs_at'] tick = frame:preprocess('{{Tick}}') cross = frame:preprocess('{{Cross}}') local table_header = result_table_header if frame.args['live_sandbox'] then table_header = result_table_live_sandbox_header end if frame.args.highlight then should_highlight = true end self.columns = 4 if self.differs_at then table_header = table_header .. '\n! scope="col" title="Различается на символе" | Разл. на' self.columns = self.columns + 1 end -- Sort results into alphabetical order. local self_sorted = {} for key, _ in pairs(self) do if key:find('^test') then table.insert(self_sorted, key) end end table.sort(self_sorted) -- Add results to the results table. for _, value in ipairs(self_sorted) do result_table:insert_format(table_header .. "\n|-\n", value) self[value](self) result_table:insert("|}\n") end local cat_failures = '[[Категория:Модули:Страницы с проваленными юнит-тестами]]' return (num_runs == 0 and "<b>Нет тестов для запуска.</b>" or num_failures == 0 and "<b style=\"color:#008000\">Все тесты успешно пройдены: " .. num_runs .. "</b>" or "<b style=\"color:#800000\">" .. num_failures .. " тестов из " .. num_runs .. " провалено.</b>" .. cat_failures ) .. "\n\n" .. frame:preprocess(result_table:concat()) end function UnitTester:new() local o = {} setmetatable(o, self) self.__index = self return o end local p = UnitTester:new() function p.run_tests(frame) return p:run(frame) end return p f88824c8866c120062332f00624435f8323f488b Шаблон:Старый-новый стиль,примечание 10 302 765 2024-04-13T19:25:38Z ruwiki>Mikhail Ryazanov 0 [[Календарная дата#Форматы записи даты]], стилевые правки wikitext text/x-wiki В случае, если дата рождения/смерти в источниках приведена по [[Юлианский календарь|старому стилю]], рекомендуется указывать её по новому стилю, а после указать в скобках отличающуюся часть даты по старому стилю. Например, * «13.05.1801 (1)» будет отображено как [[13 мая|1 (13) мая]] [[1801 год|1801]]; * «12.06.1801 (31.05)» будет отображено как 31 мая ([[12 июня]]) [[1801 год|1801]]; * «12.01.1802 (31.12.1801)» будет отображено как 31 декабря 1801 ([[12 января]] [[1802 год|1802]]). При этом в статью будут автоматически подставлены категории даты рождения/смерти по ''новому'' стилю. Учтите, что разница между датами нового и старого стиля составляет 13 дней в XX и XXI веках, 12 дней в XIX веке, 11 дней в XVIII веке, 10 дней в XVII и XVI веках (начиная с 5 (15) октября 1582 года).<noinclude>{{doc-inline}}Шаблон предназначен для подстановки в качестве примечания к полям «дата рождения», «дата смерти» для страниц документации шаблонов-карточек типа «Персона». Параметров не принимает. Вызов: {{tl|Старый-новый стиль,примечание}} {{doc-end}} [[Категория:Википедия:Шаблоны, встраиваемые в шаблоны-карточки:Личности]] </noinclude> 7f8754eb5c2401671df545a1cd8b315f66f86463 Шаблон:Replace 10 145 332 2024-04-14T07:24:11Z ruwiki>Stjn 0 обновление аналогично английскому шаблону wikitext text/x-wiki {{safesubst:<noinclude />#invoke:String|replace|source={{{1}}}|{{{2}}}|{{{3}}}|plain={{{plain|true}}}|count={{{count|}}}}}<noinclude> {{doc}} </noinclude> 7752c3c70ae8c46a89a0808aa282956866dbba5b Шаблон:Начало скрытого блока 10 196 438 2024-04-15T20:10:25Z ruwiki>Stjn 0 см. [[phab:T185674#9715417]] wikitext text/x-wiki <includeonly><templatestyles src="Шаблон:Скрытый блок/styles.css" /><!-- --><div class="mw-collapsible {{#switch: {{{состояние|{{{state|}}}}}} | expanded | autocollapse = {{{состояние|{{{state|}}}}}} | mw-collapsed }} ts-Скрытый_блок ts-Скрытый_блок-{{#switch: {{{тип|{{{type|}}}}}} | gray | transparent = {{{тип|{{{type|}}}}}} | gray }} ts-Скрытый_блок-{{#switch: {{{Ссылка|{{{ссылка|}}}}}} | none = none | right | left = {{{Ссылка|{{{ссылка|}}}}}} | right }}HideLink {{{класс_тела|{{{класс тела|}}}}}}" style="{{ifempty |до = border: | {{{Рамка|{{{border|{{{рамка|}}}}}}}}} |после=;}}{{{frame-style|{{{стиль_тела|{{{стиль тела|}}}}}}}}}"><!-- --><div class="ts-Скрытый_блок-title {{#switch: {{{Выравнивание_заголовка|{{{ta1|{{{выравнивание_заголовка|{{{выравнивание заголовка|}}}}}}}}}}}} | none = none | left | right = ts-Скрытый_блок-title-{{{Выравнивание_заголовка|{{{ta1|{{{выравнивание_заголовка|{{{выравнивание заголовка|}}}}}}}}}}}}Title }} {{{класс_заголовка|{{{класс заголовка|}}}}}}" style="<!-- -->{{ifempty |до = background-color: | {{{Фон_заголовка|{{{bg1|{{{фон_заголовка|{{{фон заголовка|}}}}}}}}}}}} |после=;}}<!-- -->{{ifempty |до = text-align: | {{{Выравнивание_заголовка|{{{ta1|{{{выравнивание_заголовка|{{{выравнивание заголовка|}}}}}}}}}}}} |после=;}}<!-- -->{{ifempty |до = font-weight: | {{{Шрифт_заголовка|{{{шрифт_заголовка|{{{шрифт заголовка|}}}}}}}}} |после=;}}<!-- -->{{ifempty |до = font-style: | {{{Наклон_заголовка|{{{наклон_заголовка|{{{наклон заголовка|}}}}}}}}} |после=;}}<!-- -->{{{Стиль_заголовка|{{{extra1|{{{стиль_заголовка|{{{стиль заголовка|}}}}}}}}}}}}"><!-- -->{{{Заголовок|{{{заголовок|{{{Заглавие|{{{заглавие|{{{Название|{{{название|{{{header|{{{title|{{{1}}}}}}}}}}}}}}}}}}}}}}}}}}}<!-- --><div class="mw-collapsible-toggle-placeholder"></div></div><!-- --><div class="mw-collapsible-content {{{класс_текста|{{{класс текста|}}}}}}" style="<!-- -->{{ifempty |до = background-color: | {{{Фон_текста|{{{bg2|{{{фон_текста|{{{фон текста|}}}}}}}}}}}} |после=;}}<!-- -->{{ifempty |до = font-weight: | {{{Шрифт_текста|{{{шрифт_текста|{{{шрифт текста|}}}}}}}}} |после=;}}<!-- -->{{ifempty |до = font-style: | {{{Наклон_текста|{{{наклон_текста|{{{наклон текста|}}}}}}}}} |после=;}}<!-- -->{{ifempty |до = text-align: | {{{Выравнивание_текста|{{{ta2|{{{выравнивание_текста|{{{выравнивание текста|}}}}}}}}}}}} |после=;}}<!-- -->{{{Стиль_текста|{{{extra2|{{{стиль_текста|{{{стиль текста|}}}}}}}}}}}}"><!-- --></includeonly><noinclude> {{doc}} </noinclude> 3b96bb802b522e629c41cddc5d44dfb2a9eb462a Модуль:Wikidata/config 828 142 326 2024-04-18T14:43:27Z ruwiki>Stjn 0 [[ВП:Откат|откат]] правок [[Special:Contribs/Stjn|Stjn]] ([[UT:Stjn|обс.]]) к версии Ghuron Scribunto text/plain -- Property configuration for Wikidata module return { global = { separator = ',&#32;', conjunction = '&#32;и&#32;', }, presets = { ['catonly'] = { datatype = 'wikibase-item', conjunction = '', invisible = true, ['value-module'] = 'Wikidata/item', ['value-function'] = 'formatCategoryOnly', references = '', category = 'P910', }, ['country'] = { datatype = 'wikibase-item', ['claim-module'] = 'Wikidata/Places', ['claim-function'] = 'formatCountryClaimWithFlag', before = '<ul><li>', separator = '</li><li>', conjunction = '</li><li>', after = '</li></ul>', }, ['from-to'] = { datatype = 'time', ['property-module'] = 'Wikidata/date', ['property-function'] = 'formatDateIntervalProperty', }, ['link'] = { ['value-module'] = 'Wikidata/link', ['value-function'] = 'fromModule', }, ['list'] = { before = '<ul><li>', separator = '</li><li>', conjunction = '</li><li>', after = '</li></ul>', }, ['name'] = { datatype = 'monolingualtext', monolingualLangTemplate = 'lang', separator = '<br>', conjunction = '<br>', }, ['place'] = { datatype = 'wikibase-item', ['claim-module'] = 'Wikidata/Places', ['claim-function'] = 'formatPlaceWithQualifiers', before = '<ul><li>', separator = '</li><li>', conjunction = '</li><li>', after = '</li></ul>', }, ['quantity (date)'] = { datatype = 'quantity', before = '<ul><li>', separator = '</li><li>', conjunction = '</li><li>', after = '</li></ul>', qualifier = 'P585', }, }, datatypes = { commonsMedia = { limit = 1, references = false, size = '274x400px', separator = '<br>', conjunction = '<br>', somevalue = '', ['value-module'] = 'Wikidata/media', ['value-function'] = 'formatCommonsMediaValue', }, ['external-id'] = { references = false, }, ['globe-coordinate'] = { limit = 1, references = false, }, url = { separator = '<br>', conjunction = '<br>', references = false, ['value-module'] = 'Wikidata/url', ['value-function'] = 'formatUrlValue', }, quantity = { siConversion = true } }, properties = { P6 = { datatype = 'wikibase-item', }, P17 = { preset = 'country', }, P18 = { datatype = 'commonsMedia', fixdouble = true, }, P19 = { preset = 'place', separator = ',</li><li>', conjunction = ' или </li><li>', }, P20 = { preset = 'place', separator = ',</li><li>', conjunction = ' или </li><li>', }, P22 = { datatype = 'wikibase-item', conjunction = ' или ' }, P25 = { datatype = 'wikibase-item', conjunction = ' или ' }, P26 = { datatype = 'wikibase-item', }, P27 = { preset = 'country', }, P31 = { datatype = 'wikibase-item', references = false, }, P37 = { datatype = 'wikibase-item', }, P39 = { datatype = 'wikibase-item', ['claim-module'] = 'Wikidata/positions', ['claim-function'] = 'formatPositionClaim', separator = '', conjunction = '', allowTables = true, }, P40 = { datatype = 'wikibase-item', }, P41 = { datatype = 'commonsMedia', size = '150x200px', }, P53 = { datatype = 'wikibase-item', category = 'P910', }, P54 = { category = 'P6112', }, P57 = { datatype = 'wikibase-item', preset = 'list', }, P58 = { datatype = 'wikibase-item', preset = 'list', }, P59 = { datatype = 'wikibase-item', category = 'P910', references = false, }, P69 = { datatype = 'wikibase-item', preset = 'list', category = 'P3876', qualifier = 'P582', }, P94 = { datatype = 'commonsMedia', size = '100x200px', }, P86 = { datatype = 'wikibase-item', preset = 'list', }, P101 = { datatype = 'wikibase-item', }, P102 = { datatype = 'wikibase-item', preset = 'list', qualifier = 'P582', category = 'P6365', }, P103 = { datatype = 'wikibase-item', }, P106 = { datatype = 'wikibase-item', ['claim-module'] = 'Wikidata/item', ['claim-function'] = 'formatEntityWithGenderClaim', conjunction = ',&#32;', }, P108 = { datatype = 'wikibase-item', preset = 'list', category = 'P4195', }, P109 = { datatype = 'commonsMedia', size = '150x150px', alt = 'Изображение автографа', }, P117 = { datatype = 'commonsMedia', size = '290x300px', alt = 'Изображение химической структуры', }, P119 = { preset = 'place', thisLocationOnly = 'true', }, P131 = { datatype = 'wikibase-item', }, P140 = { datatype = 'wikibase-item', }, P154 = { size = '220x80px', alt = 'Изображение логотипа', }, P159 = { preset = 'place', }, P161 = { preset = 'list', }, P162 = { preset = 'list', }, P163 = { datatype = 'wikibase-item', }, P166 = { datatype = 'wikibase-item', ['property-module'] = 'Wikidata/Medals', ['property-function'] = 'formatProperty', ['value-module'] = 'Wikidata/Medals', ['value-function'] = 'formatValue', before = '<div style="text-align:justify">', after = '</div>', separator = '&#32;', conjunction = '&#32;', references = false, allowTables = true, }, P190 = { datatype = 'wikibase-item', }, P212 = { preset = 'link', }, P225 = { preset = 'list', ['claim-module'] = 'Wikidata/Biology', ['claim-function'] = 'formatTaxonNameClaim', }, P237 = { datatype = 'wikibase-item', }, P241 = { datatype = 'wikibase-item', }, P242 = { datatype = 'commonsMedia', size = '300x300px', }, P247 = { formatter = 'https://nssdc.gsfc.nasa.gov/nmc/spacecraft/display.action?id=$1', }, P267 = { preset = 'link', }, P276 = { preset = 'place', }, P281 = { datatype = 'string', }, P286 = { preset = 'list', }, P296 = { formatter = 'http://osm.sbin.ru/esr/esr:$1', }, P301 = { rawArticle = true, }, P344 = { preset = 'list', }, P345 = { preset = 'link', }, P348 = { preset = 'list', ['property-module'] = 'Wikidata/Software', ['property-function'] = 'formatVersionProperty', }, P361 = { datatype = 'wikibase-item', }, P373 = { datatype = 'string', ['value-module'] = 'Wikidata/media', ['value-function'] = 'formatCommonsCategory', limit = 1, }, P374 = { datatype = 'external-id', }, P395 = { datatype = 'string', }, P407 = { datatype = 'wikibase-item', }, P410 = { datatype = 'wikibase-item', }, P412 = { datatype = 'wikibase-item', category = 'P910', }, P413 = { datatype = 'wikibase-item', ['claim-module'] = 'Wikidata/item', ['claim-function'] = 'formatEntityWithGenderClaim', conjunction = ',&#32;', category = 'P910', }, P414 = { ['claim-module'] = 'Wikidata/item', ['claim-function'] = 'applyDefaultTemplate', }, P421 = { datatype = 'wikibase-item', }, P473 = { datatype = 'string', }, P495 = { preset = 'country', }, P505 = { preset = 'list', }, P512 = { datatype = 'wikibase-item', ['property-module'] = 'Wikidata/P512', ['property-function'] = 'formatAcademicDegree', }, P527 = { preset = 'list', }, P528 = { references = false, qualifier = 'P972', }, P551 = { preset = 'place', }, P569 = { datatype = 'time', ['claim-module'] = 'Wikidata/date', ['claim-function'] = 'formatDateOfBirthClaim', }, P570 = { datatype = 'time', ['claim-module'] = 'Wikidata/date', ['claim-function'] = 'formatDateOfDeathClaim', }, P571 = { datatype = 'time', }, P576 = { datatype = 'time', }, P598 = { datatype = 'wikibase-item', }, P607 = { datatype = 'wikibase-item', preset = 'list', }, P625 = { datatype = 'globe-coordinate', }, P669 = { qualifier = 'P670', }, P685 = { formatter = 'https://www.ncbi.nlm.nih.gov/Taxonomy/Browser/wwwtax.cgi?mode=Info&id=$1', }, P721 = { preset = 'link', }, P764 = { preset = 'link', }, P803 = { datatype = 'wikibase-item', }, P856 = { datatype = 'url', }, P881 = { novalue = 'нет', category = 'P910', }, P884 = { preset = 'link', }, P915 = { category = 'P1740', }, P957 = { preset = 'link', }, P972 = { preset = 'catonly', }, P1077 = { preset = 'link', }, P1082 = { preset = 'quantity (date)', unit = 'чел.', ['property-module'] = 'Wikidata/number', ['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator' }, P1098 = { preset = 'quantity (date)', unit = 'чел.', }, P1120 = { preset = 'quantity (date)', unit = 'чел.', ['property-module'] = 'Wikidata/number', ['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator' }, P1128 = { datatype = 'quantity', preset = 'quantity (date)', unit = 'чел.', ['property-module'] = 'Wikidata/number', ['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator' }, P1114 = { datatype = 'quantity', qualifier = 'P585', }, P1174 = { preset = 'quantity (date)', unit = 'чел.', }, P1195 = { ['value-module'] = 'Wikidata/Software', ['value-function'] = 'formatExtension', conjunction = ' или ', }, P1215 = { datatype = 'quantity', ['property-module'] = 'Wikidata/number', ['property-function'] = 'formatVisualMagnitude' }, P1246 = { preset = 'link', }, P1249 = { datatype = 'time', }, P1352 = { preset = 'quantity (date)', }, P1376 = { datatype = 'wikibase-item', }, P1402 = { preset = 'link', }, P1448 = { preset = 'name', }, P1458 = { datatype = 'quantity', ['property-module'] = 'Wikidata/number', ['property-function'] = 'formatColorIndex' }, P1464 = { datatype = 'wikibase-item', }, P1476 = { preset = 'name', }, P1477 = { preset = 'name', }, P1532 = { preset = 'country', rank = '[rank:normal, rank:preferred]', }, P1543 = { datatype = 'commonsMedia', }, P1559 = { preset = 'name', }, P1603 = { preset = 'quantity (date)', unit = 'чел.', ['property-module'] = 'Wikidata/number', ['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator' }, P1621 = { size = '300x300px', }, P1692 = { preset = 'link', }, P1705 = { preset = 'name', }, P1753 = { rowArticle = true, }, P1809 = { preset = 'list', }, P1846 = { datatype = 'commonsMedia', fixdouble = true, }, P2031 = { preset = 'from-to', to = 'P2032', within = 'P570', }, P2043 = { preset = 'quantity (date)', }, P2044 = { datatype = 'quantity', }, P2046 = { preset = 'quantity (date)', siConversion = false, }, P2047 = { siConversion = false, }, P2048 = { conjunction = '&#32;или&#32;', }, P2060 = { siConversion = false, }, P2097 = { siConversion = false, }, P2120 = { siConversion = false, }, P2137 = { preset = 'quantity (date)', ['property-module'] = 'Wikidata/number', ['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator', countByThousands = true, }, P2139 = { preset = 'quantity (date)', ['property-module'] = 'Wikidata/number', ['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator', countByThousands = true, }, P2146 = { siConversion = false, }, P2214 = { siConversion = false }, P2226 = { preset = 'quantity (date)', ['property-module'] = 'Wikidata/number', ['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator', countByThousands = true, }, P2257 = { siConversion = false }, P2260 = { siConversion = false }, P2295 = { preset = 'quantity (date)', ['property-module'] = 'Wikidata/number', ['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator', countByThousands = true, }, P2324 = { datatype = 'quantity', preset = 'quantity (date)', unit = 'чел.' }, P2403 = { preset = 'quantity (date)', ['property-module'] = 'Wikidata/number', ['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator', countByThousands = true, }, P2425 = { alt = 'Изображение орденской планки', }, P2583 = { siConversion = false, }, P2597 = { preset = 'catonly', }, P2650 = { datatype = 'wikibase-item', }, P2789 = { preset = 'list', }, P2896 = { siConversion = false, }, P2910 = { size = '100x80px', }, P3083 = { formatter = 'http://simbad.u-strasbg.fr/simbad/sim-id?Ident=$1', }, P3086 = { siConversion = false, }, P3362 = { preset = 'quantity (date)', ['property-module'] = 'Wikidata/number', ['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator', countByThousands = true, }, P4614 = { category = 'P1200', }, P5348 = { siConversion = false, }, P6257 = { ['value-module'] = 'Wikidata/number', ['value-function'] = 'formatRA', }, P6258 = { ['value-module'] = 'Wikidata/number', ['value-function'] = 'formatDMS', }, P6259 = { ['references'] = false, }, P7584 = { siConversion = false, }, P8010 = { datatype = 'quantity', preset = 'quantity (date)', unit = 'чел.', ['property-module'] = 'Wikidata/number', ['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator' }, P8224 = { alt = 'Изображение молекулярной модели', }, }, categories = { ['links-to-entities-with-missing-label'] = 'Википедия:Статьи со ссылками на элементы Викиданных без подписи', ['links-to-entities-with-wikibase-error'] = 'Википедия:Страницы с ошибками скриптов, использующих Викиданные', ['links-to-entities-with-missing-local-language-label'] = 'Википедия:Статьи со ссылками на элементы Викиданных без русской подписи', ['media-contains-local-caption'] = 'Википедия:Локальная подпись у изображения из Викиданных', ['media-contains-markup'] = 'Википедия:Статьи с вики-разметкой в изображении карточки', ['media-contains-local-double'] = 'Википедия:Изображение в статье дублирует изображение в карточке', ['value-contains-table'] = 'Википедия:Статьи с табличной вставкой в карточке', }, errors = { ['property-param-not-provided'] = 'Не дан параметр свойства', ['entity-not-found'] = 'Сущность не найдена.', ['unknown-claim-type'] = 'Неизвестный тип заявления.', ['unknown-snak-type'] = 'Неизвестный тип снэка.', ['unknown-datavalue-type'] = 'Неизвестный тип значения данных.', ['unknown-entity-type'] = 'Неизвестный тип сущности.', ['unknown-property-module'] = 'Вы должны установить и property-module, и property-function.', ['unknown-claim-module'] = 'Вы должны установить и claim-module, и claim-function.', ['unknown-value-module'] = 'Вы должны установить и value-module, и value-function.', ['property-module-not-found'] = 'Модуль для отображения свойства не найден', ['property-function-not-found'] = 'Функция для отображения свойства не найдена', ['claim-module-not-found'] = 'Модуль для отображения утверждения не найден.', ['claim-function-not-found'] = 'Функция для отображения утверждения не найдена.', ['value-module-not-found'] = 'Модуль для отображения значения не найден.', ['value-function-not-found'] = 'Функция для отображения значения не найдена.', }, i18n = { somevalue = "''неизвестно''", novalue = '', -- Обстоятельства источника Q5727902 = 'около ', Q18122778 = '<span style="border-bottom: 1px dotted; cursor: help;" title="предположительно">предп.</span> ', Q30230067 = 'возможно ', Q52834024 = '<span style="border-bottom: 1px dotted; cursor: help;" title="менее чем">&lt;</span> ', Q54418095 = '<span style="border-bottom: 1px dotted; cursor: help;" title="более чем">&gt;</span> ', thousandPowers = {'', ' тыс.', ' млн', ' млрд', ' трлн'}, }, deprecatedSources = { Q355 = true, -- Facebook Q36578 = true, -- Gemeinsame Normdatei Q63056 = true, -- Find a Grave Q212256 = true, -- АиФ Q504063 = true, -- Discogs Q523660 = true, -- International Music Score Library Project by https://ru.wikipedia.org/?diff=107090748 Q1798125 = true, -- LIBRIS Q2621214 = true, -- Geni Q15222191 = true, -- BNF Q15241312 = true, -- Freebase Q19938912 = true, -- BNF Q21697707 = true, -- Хайазг Q25328680 = true, -- Prabook Q29861311 = true, -- SNAC Q86999151 = true, -- WeChangEd }, }; b786cd0414ef1bee304179c30b5daff1eda5baf8 Шаблон:Wikidata gender switch 10 273 707 2024-04-28T17:08:48Z ruwiki>Dima st bk 0 + lc по запросу на СО wikitext text/x-wiki {{#switch: {{wikidata|p21|{{lc:{{delink|{{{1|}}}}}}}|plain=true|from={{{from|}}}}} | 1 | f | fem | female | feminine | ж | жен | женский | женский пол | транс-женщина | Q6581072 | Q1052281 | Q43445 = {{{2}}} | m | male | masculine | м | муж | мужской | мужской пол | транс-мужчина | Q6581097 | Q2449503 | Q44148 = {{{3}}} | #default = {{#if:{{{4|}}}|{{{4}}}|{{{3}}}}} }}<noinclude> {{doc}} </noinclude> 24ccdd5a8702a7028386e9b887d3acf1b5f81c34 Модуль:Citation/CS1 828 78 128 2024-04-28T20:37:46Z ruwiki>Wikisaurus 0 [[Обсуждение Википедии:Шаблоны цитирования CS1/2#Обновление от 27 марта 2024]] Scribunto text/plain require ('strict'); --[[--------------------------< F O R W A R D D E C L A R A T I O N S >-------------------------------------- each of these counts against the Lua upvalue limit ]] local validation; -- functions in Module:Citation/CS1/Date_validation local utilities; -- functions in Module:Citation/CS1/Utilities local z = {}; -- table of tables in Module:Citation/CS1/Utilities local identifiers; -- functions and tables in Module:Citation/CS1/Identifiers local metadata; -- functions in Module:Citation/CS1/COinS local cfg = {}; -- table of configuration tables that are defined in Module:Citation/CS1/Configuration local whitelist = {}; -- table of tables listing valid template parameter names; defined in Module:Citation/CS1/Whitelist local boxDate = require('Module:Calendar').bxDate; -- РУВИКИ: все даты делаем человекочитаемыми --[[------------------< P A G E S C O P E V A R I A B L E S >--------------- declare variables here that have page-wide scope that are not brought in from other modules; that are created here and used here ]] local added_deprecated_cat; -- Boolean flag so that the category is added only once local added_vanc_errs; -- Boolean flag so we only emit one Vancouver error / category local added_generic_name_errs; -- Boolean flag so we only emit one generic name error / category and stop testing names once an error is encountered local added_numeric_name_errs; -- Boolean flag so we only emit one numeric name error / category and stop testing names once an error is encountered local added_numeric_name_maint; -- Boolean flag so we only emit one numeric name maint category and stop testing names once a category has been emitted local Frame; -- holds the module's frame table local is_preview_mode; -- true when article is in preview mode; false when using 'Preview page with this template' (previewing the module) local is_sandbox; -- true when using sandbox modules to render citation --[[--------------------------< F I R S T _ S E T >------------------------------------------------------------ Locates and returns the first set value in a table of values where the order established in the table, left-to-right (or top-to-bottom), is the order in which the values are evaluated. Returns nil if none are set. This version replaces the original 'for _, val in pairs do' and a similar version that used ipairs. With the pairs version the order of evaluation could not be guaranteed. With the ipairs version, a nil value would terminate the for-loop before it reached the actual end of the list. ]] local function first_set (list, count) local i = 1; while i <= count do -- loop through all items in list if utilities.is_set( list[i] ) then return list[i]; -- return the first set list member end i = i + 1; -- point to next end end --[[--------------------------< A D D _ V A N C _ E R R O R >---------------------------------------------------- Adds a single Vancouver system error message to the template's output regardless of how many error actually exist. To prevent duplication, added_vanc_errs is nil until an error message is emitted. added_vanc_errs is a Boolean declared in page scope variables above ]] local function add_vanc_error (source, position) if added_vanc_errs then return end added_vanc_errs = true; -- note that we've added this category utilities.set_message ('err_vancouver', {source, position}); end --[[--------------------------< I S _ S C H E M E >------------------------------------------------------------ does this thing that purports to be a URI scheme seem to be a valid scheme? The scheme is checked to see if it is in agreement with http://tools.ietf.org/html/std66#section-3.1 which says: Scheme names consist of a sequence of characters beginning with a letter and followed by any combination of letters, digits, plus ("+"), period ("."), or hyphen ("-"). returns true if it does, else false ]] local function is_scheme (scheme) return scheme and scheme:match ('^%a[%a%d%+%.%-]*:'); -- true if scheme is set and matches the pattern end --[=[-------------------------< I S _ D O M A I N _ N A M E >-------------------------------------------------- Does this thing that purports to be a domain name seem to be a valid domain name? Syntax defined here: http://tools.ietf.org/html/rfc1034#section-3.5 BNF defined here: https://tools.ietf.org/html/rfc4234 Single character names are generally reserved; see https://tools.ietf.org/html/draft-ietf-dnsind-iana-dns-01#page-15; see also [[Single-letter second-level domain]] list of TLDs: https://www.iana.org/domains/root/db RFC 952 (modified by RFC 1123) requires the first and last character of a hostname to be a letter or a digit. Between the first and last characters the name may use letters, digits, and the hyphen. Also allowed are IPv4 addresses. IPv6 not supported domain is expected to be stripped of any path so that the last character in the last character of the TLD. tld is two or more alpha characters. Any preceding '//' (from splitting a URL with a scheme) will be stripped here. Perhaps not necessary but retained in case it is necessary for IPv4 dot decimal. There are several tests: the first character of the whole domain name including subdomains must be a letter or a digit internationalized domain name (ASCII characters with .xn-- ASCII Compatible Encoding (ACE) prefix xn-- in the TLD) see https://tools.ietf.org/html/rfc3490 single-letter/digit second-level domains in the .org, .cash, and .today TLDs q, x, and z SL domains in the .com TLD i and q SL domains in the .net TLD single-letter SL domains in the ccTLDs (where the ccTLD is two letters) two-character SL domains in gTLDs (where the gTLD is two or more letters) three-plus-character SL domains in gTLDs (where the gTLD is two or more letters) IPv4 dot-decimal address format; TLD not allowed returns true if domain appears to be a proper name and TLD or IPv4 address, else false ]=] local function is_domain_name (domain) if not domain then return false; -- if not set, abandon end domain = domain:gsub ('^//', ''); -- strip '//' from domain name if present; done here so we only have to do it once if not domain:match ('^[%w]') then -- first character must be letter or digit return false; end if domain:match ('^%a+:') then -- hack to detect things that look like s:Page:Title where Page: is namespace at Wikisource return false; end local patterns = { -- patterns that look like URLs '%f[%w][%w][%w%-]+[%w]%.%a%a+$', -- three or more character hostname.hostname or hostname.tld '%f[%w][%w][%w%-]+[%w]%.xn%-%-[%w]+$', -- internationalized domain name with ACE prefix '%f[%a][qxz]%.com$', -- assigned one character .com hostname (x.com times out 2015-12-10) '%f[%a][iq]%.net$', -- assigned one character .net hostname (q.net registered but not active 2015-12-10) '%f[%w][%w]%.%a%a$', -- one character hostname and ccTLD (2 chars) '%f[%w][%w][%w]%.%a%a+$', -- two character hostname and TLD '^%d%d?%d?%.%d%d?%d?%.%d%d?%d?%.%d%d?%d?', -- IPv4 address } for _, pattern in ipairs (patterns) do -- loop through the patterns list if domain:match (pattern) then return true; -- if a match then we think that this thing that purports to be a URL is a URL end end for _, d in ipairs (cfg.single_letter_2nd_lvl_domains_t) do -- look for single letter second level domain names for these top level domains if domain:match ('%f[%w][%w]%.' .. d) then return true end end return false; -- no matches, we don't know what this thing is end --[[--------------------------< I S _ U R L >------------------------------------------------------------------ returns true if the scheme and domain parts of a URL appear to be a valid URL; else false. This function is the last step in the validation process. This function is separate because there are cases that are not covered by split_url(), for example is_parameter_ext_wikilink() which is looking for bracketted external wikilinks. ]] local function is_url (scheme, domain) if utilities.is_set (scheme) then -- if scheme is set check it and domain return is_scheme (scheme) and is_domain_name (domain); else return is_domain_name (domain); -- scheme not set when URL is protocol-relative end end --[[--------------------------< S P L I T _ U R L >------------------------------------------------------------ Split a URL into a scheme, authority indicator, and domain. First remove Fully Qualified Domain Name terminator (a dot following TLD) (if any) and any path(/), query(?) or fragment(#). If protocol-relative URL, return nil scheme and domain else return nil for both scheme and domain. When not protocol-relative, get scheme, authority indicator, and domain. If there is an authority indicator (one or more '/' characters immediately following the scheme's colon), make sure that there are only 2. Any URL that does not have news: scheme must have authority indicator (//). TODO: are there other common schemes like news: that don't use authority indicator? Strip off any port and path; ]] local function split_url (url_str) local scheme, authority, domain; url_str = url_str:gsub ('([%a%d])%.?[/%?#].*$', '%1'); -- strip FQDN terminator and path(/), query(?), fragment (#) (the capture prevents false replacement of '//') if url_str:match ('^//%S*') then -- if there is what appears to be a protocol-relative URL domain = url_str:match ('^//(%S*)') elseif url_str:match ('%S-:/*%S+') then -- if there is what appears to be a scheme, optional authority indicator, and domain name scheme, authority, domain = url_str:match ('(%S-:)(/*)(%S+)'); -- extract the scheme, authority indicator, and domain portions if utilities.is_set (authority) then authority = authority:gsub ('//', '', 1); -- replace place 1 pair of '/' with nothing; if utilities.is_set(authority) then -- if anything left (1 or 3+ '/' where authority should be) then return scheme; -- return scheme only making domain nil which will cause an error message end else if not scheme:match ('^news:') then -- except for news:..., MediaWiki won't link URLs that do not have authority indicator; TODO: a better way to do this test? return scheme; -- return scheme only making domain nil which will cause an error message end end domain = domain:gsub ('(%a):%d+', '%1'); -- strip port number if present end return scheme, domain; end --[[--------------------------< L I N K _ P A R A M _ O K >--------------------------------------------------- checks the content of |title-link=, |series-link=, |author-link=, etc. for properly formatted content: no wikilinks, no URLs Link parameters are to hold the title of a Wikipedia article, so none of the WP:TITLESPECIALCHARACTERS are allowed: # < > [ ] | { } _ except the underscore which is used as a space in wiki URLs and # which is used for section links returns false when the value contains any of these characters. When there are no illegal characters, this function returns TRUE if value DOES NOT appear to be a valid URL (the |<param>-link= parameter is ok); else false when value appears to be a valid URL (the |<param>-link= parameter is NOT ok). ]] local function link_param_ok (value) local scheme, domain; if value:find ('[<>%[%]|{}]') then -- if any prohibited characters return false; end scheme, domain = split_url (value); -- get scheme or nil and domain or nil from URL; return not is_url (scheme, domain); -- return true if value DOES NOT appear to be a valid URL end --[[--------------------------< L I N K _ T I T L E _ O K >--------------------------------------------------- Use link_param_ok() to validate |<param>-link= value and its matching |<title>= value. |<title>= may be wiki-linked but not when |<param>-link= has a value. This function emits an error message when that condition exists check <link> for inter-language interwiki-link prefix. prefix must be a MediaWiki-recognized language code and must begin with a colon. ]] local function link_title_ok (link, lorig, title, torig) local orig; if utilities.is_set (link) then -- don't bother if <param>-link doesn't have a value if not link_param_ok (link) then -- check |<param>-link= markup orig = lorig; -- identify the failing link parameter elseif title:find ('%[%[') then -- check |title= for wikilink markup orig = torig; -- identify the failing |title= parameter elseif link:match ('^%a+:') then -- if the link is what looks like an interwiki local prefix = link:match ('^(%a+):'):lower(); -- get the interwiki prefix if cfg.inter_wiki_map[prefix] then -- if prefix is in the map, must have preceding colon orig = lorig; -- flag as error end end end if utilities.is_set (orig) then link = ''; -- unset utilities.set_message ('err_bad_paramlink', orig); -- URL or wikilink in |title= with |title-link=; end return link; -- link if ok, empty string else end --[[--------------------------< C H E C K _ U R L >------------------------------------------------------------ Determines whether a URL string appears to be valid. First we test for space characters. If any are found, return false. Then split the URL into scheme and domain portions, or for protocol-relative (//example.com) URLs, just the domain. Use is_url() to validate the two portions of the URL. If both are valid, or for protocol-relative if domain is valid, return true, else false. Because it is different from a standard URL, and because this module used external_link() to make external links that work for standard and news: links, we validate newsgroup names here. The specification for a newsgroup name is at https://tools.ietf.org/html/rfc5536#section-3.1.4 ]] local function check_url( url_str ) if nil == url_str:match ("^%S+$") then -- if there are any spaces in |url=value it can't be a proper URL return false; end local scheme, domain; scheme, domain = split_url (url_str); -- get scheme or nil and domain or nil from URL; if 'news:' == scheme then -- special case for newsgroups return domain:match('^[%a%d%+%-_]+%.[%a%d%+%-_%.]*[%a%d%+%-_]$'); end return is_url (scheme, domain); -- return true if value appears to be a valid URL end --[=[-------------------------< I S _ P A R A M E T E R _ E X T _ W I K I L I N K >---------------------------- Return true if a parameter value has a string that begins and ends with square brackets [ and ] and the first non-space characters following the opening bracket appear to be a URL. The test will also find external wikilinks that use protocol-relative URLs. Also finds bare URLs. The frontier pattern prevents a match on interwiki-links which are similar to scheme:path URLs. The tests that find bracketed URLs are required because the parameters that call this test (currently |title=, |chapter=, |work=, and |publisher=) may have wikilinks and there are articles or redirects like '//Hus' so, while uncommon, |title=[[//Hus]] is possible as might be [[en://Hus]]. ]=] local function is_parameter_ext_wikilink (value) local scheme, domain; if value:match ('%f[%[]%[%a%S*:%S+.*%]') then -- if ext. wikilink with scheme and domain: [xxxx://yyyyy.zzz] scheme, domain = split_url (value:match ('%f[%[]%[(%a%S*:%S+).*%]')); elseif value:match ('%f[%[]%[//%S+.*%]') then -- if protocol-relative ext. wikilink: [//yyyyy.zzz] scheme, domain = split_url (value:match ('%f[%[]%[(//%S+).*%]')); elseif value:match ('%a%S*:%S+') then -- if bare URL with scheme; may have leading or trailing plain text scheme, domain = split_url (value:match ('(%a%S*:%S+)')); elseif value:match ('//%S+') then -- if protocol-relative bare URL: //yyyyy.zzz; may have leading or trailing plain text scheme, domain = split_url (value:match ('(//%S+)')); -- what is left should be the domain else return false; -- didn't find anything that is obviously a URL end return is_url (scheme, domain); -- return true if value appears to be a valid URL end --[[-------------------------< C H E C K _ F O R _ U R L >----------------------------------------------------- loop through a list of parameters and their values. Look at the value and if it has an external link, emit an error message. ]] local function check_for_url (parameter_list, error_list) for k, v in pairs (parameter_list) do -- for each parameter in the list if is_parameter_ext_wikilink (v) then -- look at the value; if there is a URL add an error message table.insert (error_list, utilities.wrap_style ('parameter', k)); end end end --[[--------------------------< S A F E _ F O R _ U R L >------------------------------------------------------ Escape sequences for content that will be used for URL descriptions ]] local function safe_for_url( str ) if str:match( "%[%[.-%]%]" ) ~= nil then utilities.set_message ('err_wikilink_in_url', {}); end return str:gsub( '[%[%]\n]', { ['['] = '&#91;', [']'] = '&#93;', ['\n'] = ' ' } ); end --[[--------------------------< E X T E R N A L _ L I N K >---------------------------------------------------- Format an external link with error checking ]] local function external_link (URL, label, source, access) local err_msg = ''; local domain; local path; local base_url; if not utilities.is_set (label) then label = URL; if utilities.is_set (source) then utilities.set_message ('err_bare_url_missing_title', {utilities.wrap_style ('parameter', source)}); else error (cfg.messages["bare_url_no_origin"]); -- programmer error; valid parameter name does not have matching meta-parameter end end if not check_url (URL) then utilities.set_message ('err_bad_url', {utilities.wrap_style ('parameter', source)}); end domain, path = URL:match ('^([/%.%-%+:%a%d]+)([/%?#].*)$'); -- split the URL into scheme plus domain and path if path then -- if there is a path portion path = path:gsub ('[%[%]]', {['['] = '%5b', [']'] = '%5d'}); -- replace '[' and ']' with their percent-encoded values URL = table.concat ({domain, path}); -- and reassemble end base_url = table.concat ({ "[", URL, " ", safe_for_url (label), "]" }); -- assemble a wiki-markup URL if utilities.is_set (access) then -- access level (subscription, registration, limited) base_url = utilities.substitute (cfg.presentation['ext-link-access-signal'], {cfg.presentation[access].class, cfg.presentation[access].title, base_url}); -- add the appropriate icon end return base_url; end --[[--------------------------< F O R M A T E _ D A T E >----------------------------------------------------- Call a calendar module that turns all non-local language dates (including ISO dates) into local language dates. Used for archiving and review dates. ]] local function formatDate(txtDateIn, strFormat, params) local txtDateOut, date, status = boxDate(txtDateIn, strFormat, params) if status.brk then return error(status.errorText) else return txtDateOut end end --[[--------------------------< D E P R E C A T E D _ P A R A M E T E R >-------------------------------------- Categorize and emit an error message when the citation contains one or more deprecated parameters. The function includes the offending parameter name to the error message. Only one error message is emitted regardless of the number of deprecated parameters in the citation. added_deprecated_cat is a Boolean declared in page scope variables above ]] local function deprecated_parameter(name) if not added_deprecated_cat then added_deprecated_cat = true; -- note that we've added this category utilities.set_message ('err_deprecated_params', {name}); -- add error message end end --[=[-------------------------< K E R N _ Q U O T E S >-------------------------------------------------------- Apply kerning to open the space between the quote mark provided by the module and a leading or trailing quote mark contained in a |title= or |chapter= parameter's value. This function will positive kern either single or double quotes: "'Unkerned title with leading and trailing single quote marks'" " 'Kerned title with leading and trailing single quote marks' " (in real life the kerning isn't as wide as this example) Double single quotes (italic or bold wiki-markup) are not kerned. Replaces Unicode quote marks in plain text or in the label portion of a [[L|D]] style wikilink with typewriter quote marks regardless of the need for kerning. Unicode quote marks are not replaced in simple [[D]] wikilinks. Call this function for chapter titles, for website titles, etc.; not for book titles. ]=] local function kern_quotes (str) local cap = ''; local wl_type, label, link; wl_type, label, link = utilities.is_wikilink (str); -- wl_type is: 0, no wl (text in label variable); 1, [[D]]; 2, [[L|D]] if 1 == wl_type then -- [[D]] simple wikilink with or without quote marks if mw.ustring.match (str, '%[%[[\"“”\'‘’].+[\"“”\'‘’]%]%]') then -- leading and trailing quote marks str = utilities.substitute (cfg.presentation['kern-left'], str); str = utilities.substitute (cfg.presentation['kern-right'], str); elseif mw.ustring.match (str, '%[%[[\"“”\'‘’].+%]%]') then -- leading quote marks str = utilities.substitute (cfg.presentation['kern-left'], str); elseif mw.ustring.match (str, '%[%[.+[\"“”\'‘’]%]%]') then -- trailing quote marks str = utilities.substitute (cfg.presentation['kern-right'], str); end else -- plain text or [[L|D]]; text in label variable label = mw.ustring.gsub (label, '[“”]', '\"'); -- replace “” (U+201C & U+201D) with " (typewriter double quote mark) label = mw.ustring.gsub (label, '[‘’]', '\''); -- replace ‘’ (U+2018 & U+2019) with ' (typewriter single quote mark) cap = mw.ustring.match (label, "^([\"\'][^\'].+)"); -- match leading double or single quote but not doubled single quotes (italic markup) if utilities.is_set (cap) then label = utilities.substitute (cfg.presentation['kern-left'], cap); end cap = mw.ustring.match (label, "^(.+[^\'][\"\'])$") -- match trailing double or single quote but not doubled single quotes (italic markup) if utilities.is_set (cap) then label = utilities.substitute (cfg.presentation['kern-right'], cap); end if 2 == wl_type then str = utilities.make_wikilink (link, label); -- reassemble the wikilink else str = label; end end return str; end --[[--------------------------< F O R M A T _ S C R I P T _ V A L U E >---------------------------------------- |script-title= holds title parameters that are not written in Latin-based scripts: Chinese, Japanese, Arabic, Hebrew, etc. These scripts should not be italicized and may be written right-to-left. The value supplied by |script-title= is concatenated onto Title after Title has been wrapped in italic markup. Regardless of language, all values provided by |script-title= are wrapped in <bdi>...</bdi> tags to isolate RTL languages from the English left to right. |script-title= provides a unique feature. The value in |script-title= may be prefixed with a two-character ISO 639-1 language code and a colon: |script-title=ja:*** *** (where * represents a Japanese character) Spaces between the two-character code and the colon and the colon and the first script character are allowed: |script-title=ja : *** *** |script-title=ja: *** *** |script-title=ja :*** *** Spaces preceding the prefix are allowed: |script-title = ja:*** *** The prefix is checked for validity. If it is a valid ISO 639-1 language code, the lang attribute (lang="ja") is added to the <bdi> tag so that browsers can know the language the tag contains. This may help the browser render the script more correctly. If the prefix is invalid, the lang attribute is not added. At this time there is no error message for this condition. Supports |script-title=, |script-chapter=, |script-<periodical>= ]] local function format_script_value (script_value, script_param) local lang=''; -- initialize to empty string local name; if script_value:match('^%l%l%l?%s*:') then -- if first 3 or 4 non-space characters are script language prefix lang = script_value:match('^(%l%l%l?)%s*:%s*%S.*'); -- get the language prefix or nil if there is no script if not utilities.is_set (lang) then utilities.set_message ('err_script_parameter', {script_param, cfg.err_msg_supl['missing title part']}); -- prefix without 'title'; add error message return ''; -- script_value was just the prefix so return empty string end -- if we get this far we have prefix and script name = cfg.lang_tag_remap[lang] or mw.language.fetchLanguageName( lang, cfg.this_wiki_code ); -- get language name so that we can use it to categorize if utilities.is_set (name) then -- is prefix a proper ISO 639-1 language code? script_value = script_value:gsub ('^%l+%s*:%s*', ''); -- strip prefix from script -- is prefix one of these language codes? if utilities.in_array (lang, cfg.script_lang_codes) then utilities.add_prop_cat ('script', {name, lang}) else utilities.set_message ('err_script_parameter', {script_param, cfg.err_msg_supl['unknown language code']}); -- unknown script-language; add error message end lang = ' lang="' .. lang .. '" '; -- convert prefix into a lang attribute else utilities.set_message ('err_script_parameter', {script_param, cfg.err_msg_supl['invalid language code']}); -- invalid language code; add error message lang = ''; -- invalid so set lang to empty string end else utilities.set_message ('err_script_parameter', {script_param, cfg.err_msg_supl['missing prefix']}); -- no language code prefix; add error message end script_value = utilities.substitute (cfg.presentation['bdi'], {lang, script_value}); -- isolate in case script is RTL return script_value; end --[[--------------------------< S C R I P T _ C O N C A T E N A T E >------------------------------------------ Initially for |title= and |script-title=, this function concatenates those two parameter values after the script value has been wrapped in <bdi> tags. ]] local function script_concatenate (title, script, script_param) if utilities.is_set (script) then script = format_script_value (script, script_param); -- <bdi> tags, lang attribute, categorization, etc.; returns empty string on error if utilities.is_set (script) then title = title .. ' ' .. script; -- concatenate title and script title end end return title; end --[[--------------------------< W R A P _ M S G >-------------------------------------------------------------- Applies additional message text to various parameter values. Supplied string is wrapped using a message_list configuration taking one argument. Supports lower case text for {{citation}} templates. Additional text taken from citation_config.messages - the reason this function is similar to but separate from wrap_style(). ]] local function wrap_msg (key, str, lower) if not utilities.is_set ( str ) then return ""; end if true == lower then local msg; msg = cfg.messages[key]:lower(); -- set the message to lower case before return utilities.substitute ( msg, str ); -- including template text else return utilities.substitute ( cfg.messages[key], str ); end end --[[----------------< W I K I S O U R C E _ U R L _ M A K E >------------------- Makes a Wikisource URL from Wikisource interwiki-link. Returns the URL and appropriate label; nil else. str is the value assigned to |chapter= (or aliases) or |title= or |title-link= ]] local function wikisource_url_make (str) local wl_type, D, L; local ws_url, ws_label; local wikisource_prefix = table.concat ({'https://', cfg.this_wiki_code, '.wikisource.org/wiki/'}); wl_type, D, L = utilities.is_wikilink (str); -- wl_type is 0 (not a wikilink), 1 (simple wikilink), 2 (complex wikilink) if 0 == wl_type then -- not a wikilink; might be from |title-link= str = D:match ('^[Ww]ikisource:(.+)') or D:match ('^[Ss]:(.+)'); -- article title from interwiki link with long-form or short-form namespace if utilities.is_set (str) then ws_url = table.concat ({ -- build a Wikisource URL wikisource_prefix, -- prefix str, -- article title }); ws_label = str; -- label for the URL end elseif 1 == wl_type then -- simple wikilink: [[Wikisource:ws article]] str = D:match ('^[Ww]ikisource:(.+)') or D:match ('^[Ss]:(.+)'); -- article title from interwiki link with long-form or short-form namespace if utilities.is_set (str) then ws_url = table.concat ({ -- build a Wikisource URL wikisource_prefix, -- prefix str, -- article title }); ws_label = str; -- label for the URL end elseif 2 == wl_type then -- non-so-simple wikilink: [[Wikisource:ws article|displayed text]] ([[L|D]]) str = L:match ('^[Ww]ikisource:(.+)') or L:match ('^[Ss]:(.+)'); -- article title from interwiki link with long-form or short-form namespace if utilities.is_set (str) then ws_label = D; -- get ws article name from display portion of interwiki link ws_url = table.concat ({ -- build a Wikisource URL wikisource_prefix, -- prefix str, -- article title without namespace from link portion of wikilink }); end end if ws_url then ws_url = mw.uri.encode (ws_url, 'WIKI'); -- make a usable URL ws_url = ws_url:gsub ('%%23', '#'); -- undo percent-encoding of fragment marker end return ws_url, ws_label, L or D; -- return proper URL or nil and a label or nil end --[[----------------< F O R M A T _ P E R I O D I C A L >----------------------- Format the three periodical parameters: |script-<periodical>=, |<periodical>=, and |trans-<periodical>= into a single Periodical meta-parameter. ]] local function format_periodical (script_periodical, script_periodical_source, periodical, trans_periodical) if not utilities.is_set (periodical) then periodical = ''; -- to be safe for concatenation else periodical = utilities.wrap_style ('italic-title', periodical); -- style end periodical = script_concatenate (periodical, script_periodical, script_periodical_source); -- <bdi> tags, lang attribute, categorization, etc.; must be done after title is wrapped if utilities.is_set (trans_periodical) then trans_periodical = utilities.wrap_style ('trans-italic-title', trans_periodical); if utilities.is_set (periodical) then periodical = periodical .. ' ' .. trans_periodical; else -- here when trans-periodical without periodical or script-periodical periodical = trans_periodical; utilities.set_message ('err_trans_missing_title', {'periodical'}); end end return periodical; end --[[------------------< F O R M A T _ C H A P T E R _ T I T L E >--------------- Format the four chapter parameters: |script-chapter=, |chapter=, |trans-chapter=, and |chapter-url= into a single chapter meta- parameter (chapter_url_source used for error messages). ]] local function format_chapter_title (script_chapter, script_chapter_source, chapter, chapter_source, trans_chapter, trans_chapter_source, chapter_url, chapter_url_source, no_quotes, access) local ws_url, ws_label, L = wikisource_url_make (chapter); -- make a wikisource URL and label from a wikisource interwiki link if ws_url then ws_label = ws_label:gsub ('_', ' '); -- replace underscore separators with space characters chapter = ws_label; end if not utilities.is_set (chapter) then chapter = ''; -- to be safe for concatenation else if false == no_quotes then chapter = kern_quotes (chapter); -- if necessary, separate chapter title's leading and trailing quote marks from module provided quote marks chapter = utilities.wrap_style ('quoted-title', chapter); end end chapter = script_concatenate (chapter, script_chapter, script_chapter_source); -- <bdi> tags, lang attribute, categorization, etc.; must be done after title is wrapped if utilities.is_set (chapter_url) then chapter = external_link (chapter_url, chapter, chapter_url_source, access); -- adds bare_url_missing_title error if appropriate elseif ws_url then chapter = external_link (ws_url, chapter .. '&nbsp;', 'ws link in chapter'); -- adds bare_url_missing_title error if appropriate; space char to move icon away from chap text; TODO: better way to do this? chapter = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], L, chapter}); end if utilities.is_set (trans_chapter) then trans_chapter = utilities.wrap_style ('trans-quoted-title', trans_chapter); if utilities.is_set (chapter) then chapter = chapter .. ' ' .. trans_chapter; else -- here when trans_chapter without chapter or script-chapter chapter = trans_chapter; chapter_source = trans_chapter_source:match ('trans%-?(.+)'); -- when no chapter, get matching name from trans-<param> utilities.set_message ('err_trans_missing_title', {chapter_source}); end end return chapter; end --[[----------------< H A S _ I N V I S I B L E _ C H A R S >------------------- This function searches a parameter's value for non-printable or invisible characters. The search stops at the first match. This function will detect the visible replacement character when it is part of the Wikisource. Detects but ignores nowiki and math stripmarkers. Also detects other named stripmarkers (gallery, math, pre, ref) and identifies them with a slightly different error message. See also coins_cleanup(). Output of this function is an error message that identifies the character or the Unicode group, or the stripmarker that was detected along with its position (or, for multi-byte characters, the position of its first byte) in the parameter value. ]] local function has_invisible_chars (param, v) local position = ''; -- position of invisible char or starting position of stripmarker local capture; -- used by stripmarker detection to hold name of the stripmarker local stripmarker; -- boolean set true when a stripmarker is found capture = string.match (v, '[%w%p ]*'); -- test for values that are simple ASCII text and bypass other tests if true if capture == v then -- if same there are no Unicode characters return; end for _, invisible_char in ipairs (cfg.invisible_chars) do local char_name = invisible_char[1]; -- the character or group name local pattern = invisible_char[2]; -- the pattern used to find it position, _, capture = mw.ustring.find (v, pattern); -- see if the parameter value contains characters that match the pattern if position and (cfg.invisible_defs.zwj == capture) then -- if we found a zero-width joiner character if mw.ustring.find (v, cfg.indic_script) then -- it's ok if one of the Indic scripts position = nil; -- unset position elseif cfg.emoji_t[mw.ustring.codepoint (v, position+1)] then -- is zwj followed by a character listed in emoji{}? position = nil; -- unset position end end if position then if 'nowiki' == capture or 'math' == capture or -- nowiki and math stripmarkers (not an error condition) ('templatestyles' == capture and utilities.in_array (param, {'id', 'quote'})) then -- templatestyles stripmarker allowed in these parameters stripmarker = true; -- set a flag elseif true == stripmarker and cfg.invisible_defs.del == capture then -- because stripmakers begin and end with the delete char, assume that we've found one end of a stripmarker position = nil; -- unset else local err_msg; if capture and not (cfg.invisible_defs.del == capture or cfg.invisible_defs.zwj == capture) then err_msg = capture .. ' ' .. char_name; else err_msg = char_name .. ' ' .. 'character'; end utilities.set_message ('err_invisible_char', {err_msg, utilities.wrap_style ('parameter', param), position}); -- add error message return; -- and done with this parameter end end end end --[[-------------------< A R G U M E N T _ W R A P P E R >---------------------- Argument wrapper. This function provides support for argument mapping defined in the configuration file so that multiple names can be transparently aliased to single internal variable. ]] local function argument_wrapper ( args ) local origin = {}; return setmetatable({ ORIGIN = function ( self, k ) local dummy = self[k]; -- force the variable to be loaded. return origin[k]; end }, { __index = function ( tbl, k ) if origin[k] ~= nil then return nil; end local args, list, v = args, cfg.aliases[k]; if type( list ) == 'table' then v, origin[k] = utilities.select_one ( args, list, 'err_redundant_parameters' ); if origin[k] == nil then origin[k] = ''; -- Empty string, not nil end elseif list ~= nil then v, origin[k] = args[list], list; else -- maybe let through instead of raising an error? -- v, origin[k] = args[k], k; error( cfg.messages['unknown_argument_map'] .. ': ' .. k); end -- Empty strings, not nil; if v == nil then v = ''; origin[k] = ''; end tbl = rawset( tbl, k, v ); return v; end, }); end --[[--------------------------< N O W R A P _ D A T E >------------------------- When date is YYYY-MM-DD format wrap in nowrap span: <span ...>YYYY-MM-DD</span>. When date is DD MMMM YYYY or is MMMM DD, YYYY then wrap in nowrap span: <span ...>DD MMMM</span> YYYY or <span ...>MMMM DD,</span> YYYY DOES NOT yet support MMMM YYYY or any of the date ranges. ]] local function nowrap_date (date) local cap = ''; local cap2 = ''; if date:match("^%d%d%d%d%-%d%d%-%d%d$") then date = utilities.substitute (cfg.presentation['nowrap1'], date); elseif date:match("^%a+%s*%d%d?,%s+%d%d%d%d$") or date:match ("^%d%d?%s*%a+%s+%d%d%d%d$") then cap, cap2 = string.match (date, "^(.*)%s+(%d%d%d%d)$"); date = utilities.substitute (cfg.presentation['nowrap2'], {cap, cap2}); end return date; end --[[--------------------------< S E T _ T I T L E T Y P E >--------------------- This function sets default title types (equivalent to the citation including |type=<default value>) for those templates that have defaults. Also handles the special case where it is desirable to omit the title type from the rendered citation (|type=none). ]] local function set_titletype (cite_class, title_type) if utilities.is_set (title_type) then if 'none' == cfg.keywords_xlate[title_type] then title_type = ''; -- if |type=none then type parameter not displayed end return title_type; -- if |type= has been set to any other value use that value end return cfg.title_types [cite_class] or ''; -- set template's default title type; else empty string for concatenation end --[[--------------------------< S A F E _ J O I N >----------------------------- Joins a sequence of strings together while checking for duplicate separation characters. ]] local function safe_join( tbl, duplicate_char ) local f = {}; -- create a function table appropriate to type of 'duplicate character' if 1 == #duplicate_char then -- for single byte ASCII characters use the string library functions f.gsub = string.gsub f.match = string.match f.sub = string.sub else -- for multi-byte characters use the ustring library functions f.gsub = mw.ustring.gsub f.match = mw.ustring.match f.sub = mw.ustring.sub end local str = ''; -- the output string local comp = ''; -- what does 'comp' mean? local end_chr = ''; local trim; for _, value in ipairs( tbl ) do if value == nil then value = ''; end if str == '' then -- if output string is empty str = value; -- assign value to it (first time through the loop) elseif value ~= '' then if value:sub(1, 1) == '<' then -- special case of values enclosed in spans and other markup. comp = value:gsub( "%b<>", "" ); -- remove HTML markup (<span>string</span> -> string) else comp = value; end -- typically duplicate_char is sepc if f.sub(comp, 1, 1) == duplicate_char then -- is first character same as duplicate_char? why test first character? -- Because individual string segments often (always?) begin with terminal punct for the -- preceding segment: 'First element' .. 'sepc next element' .. etc.? trim = false; end_chr = f.sub(str, -1, -1); -- get the last character of the output string -- str = str .. "<HERE(enchr=" .. end_chr .. ")" -- debug stuff? if end_chr == duplicate_char then -- if same as separator str = f.sub(str, 1, -2); -- remove it elseif end_chr == "'" then -- if it might be wiki-markup if f.sub(str, -3, -1) == duplicate_char .. "''" then -- if last three chars of str are sepc'' str = f.sub(str, 1, -4) .. "''"; -- remove them and add back '' elseif f.sub(str, -5, -1) == duplicate_char .. "]]''" then -- if last five chars of str are sepc]]'' trim = true; -- why? why do this and next differently from previous? elseif f.sub(str, -4, -1) == duplicate_char .. "]''" then -- if last four chars of str are sepc]'' trim = true; -- same question end elseif end_chr == "]" then -- if it might be wiki-markup if f.sub(str, -3, -1) == duplicate_char .. "]]" then -- if last three chars of str are sepc]] wikilink trim = true; elseif f.sub(str, -3, -1) == duplicate_char .. '"]' then -- if last three chars of str are sepc"] quoted external link trim = true; elseif f.sub(str, -2, -1) == duplicate_char .. "]" then -- if last two chars of str are sepc] external link trim = true; elseif f.sub(str, -4, -1) == duplicate_char .. "'']" then -- normal case when |url=something & |title=Title. trim = true; end elseif end_chr == " " then -- if last char of output string is a space if f.sub(str, -2, -1) == duplicate_char .. " " then -- if last two chars of str are <sepc><space> str = f.sub(str, 1, -3); -- remove them both end end if trim then if value ~= comp then -- value does not equal comp when value contains HTML markup local dup2 = duplicate_char; if f.match(dup2, "%A" ) then dup2 = "%" .. dup2; end -- if duplicate_char not a letter then escape it value = f.gsub(value, "(%b<>)" .. dup2, "%1", 1 ) -- remove duplicate_char if it follows HTML markup else value = f.sub(value, 2, -1 ); -- remove duplicate_char when it is first character end end end str = str .. value; -- add it to the output string end end return str; end --[[--------------------------< I S _ S U F F I X >----------------------------- returns true if suffix is properly formed Jr, Sr, or ordinal in the range 1–9. Puncutation not allowed. ]] local function is_suffix (suffix) if utilities.in_array (suffix, {'Jr', 'Sr', 'Jnr', 'Snr', '1st', '2nd', '3rd'}) or suffix:match ('^%dth$') then return true; end return false; end --[[--------------------< I S _ G O O D _ V A N C _ N A M E >------------------- For Vancouver style, author/editor names are supposed to be rendered in Latin (read ASCII) characters. When a name uses characters that contain diacritical marks, those characters are to be converted to the corresponding Latin character. When a name is written using a non-Latin alphabet or logogram, that name is to be transliterated into Latin characters. The module doesn't do this so editors may/must. This test allows |first= and |last= names to contain any of the letters defined in the four Unicode Latin character sets [http://www.unicode.org/charts/PDF/U0000.pdf C0 Controls and Basic Latin] 0041–005A, 0061–007A [http://www.unicode.org/charts/PDF/U0080.pdf C1 Controls and Latin-1 Supplement] 00C0–00D6, 00D8–00F6, 00F8–00FF [http://www.unicode.org/charts/PDF/U0100.pdf Latin Extended-A] 0100–017F [http://www.unicode.org/charts/PDF/U0180.pdf Latin Extended-B] 0180–01BF, 01C4–024F |lastn= also allowed to contain hyphens, spaces, and apostrophes. (http://www.ncbi.nlm.nih.gov/books/NBK7271/box/A35029/) |firstn= also allowed to contain hyphens, spaces, apostrophes, and periods This original test: if nil == mw.ustring.find (last, "^[A-Za-zÀ-ÖØ-öø-ƿDŽ-ɏ%-%s%']*$") or nil == mw.ustring.find (first, "^[A-Za-zÀ-ÖØ-öø-ƿDŽ-ɏ%-%s%'%.]+[2-6%a]*$") then was written outside of the code editor and pasted here because the code editor gets confused between character insertion point and cursor position. The test has been rewritten to use decimal character escape sequence for the individual bytes of the Unicode characters so that it is not necessary to use an external editor to maintain this code. \195\128-\195\150 – À-Ö (U+00C0–U+00D6 – C0 controls) \195\152-\195\182 – Ø-ö (U+00D8-U+00F6 – C0 controls) \195\184-\198\191 – ø-ƿ (U+00F8-U+01BF – C0 controls, Latin extended A & B) \199\132-\201\143 – DŽ-ɏ (U+01C4-U+024F – Latin extended B) ]] local function is_good_vanc_name (last, first, suffix, position) if not suffix then if first:find ('[,%s]') then -- when there is a space or comma, might be first name/initials + generational suffix first = first:match ('(.-)[,%s]+'); -- get name/initials suffix = first:match ('[,%s]+(.+)$'); -- get generational suffix end end if utilities.is_set (suffix) then if not is_suffix (suffix) then add_vanc_error (cfg.err_msg_supl.suffix, position); return false; -- not a name with an appropriate suffix end end if nil == mw.ustring.find (last, "^[A-Za-z\195\128-\195\150\195\152-\195\182\195\184-\198\191\199\132-\201\143\225\184\128-\225\187\191%-%s%']*$") or nil == mw.ustring.find (first, "^[A-Za-z\195\128-\195\150\195\152-\195\182\195\184-\198\191\199\132-\201\143\225\184\128-\225\187\191%-%s%'%.]*$") then add_vanc_error (cfg.err_msg_supl['non-Latin char'], position); return false; -- not a string of Latin characters; Vancouver requires Romanization end; return true; end --[[--------------------------< R E D U C E _ T O _ I N I T I A L S >------------------------------------------ Attempts to convert names to initials in support of |name-list-style=vanc. Names in |firstn= may be separated by spaces or hyphens, or for initials, a period. See http://www.ncbi.nlm.nih.gov/books/NBK7271/box/A35062/. Vancouver style requires family rank designations (Jr, II, III, etc.) to be rendered as Jr, 2nd, 3rd, etc. See http://www.ncbi.nlm.nih.gov/books/NBK7271/box/A35085/. This code only accepts and understands generational suffix in the Vancouver format because Roman numerals look like, and can be mistaken for, initials. This function uses ustring functions because firstname initials may be any of the Unicode Latin characters accepted by is_good_vanc_name (). ]] local function reduce_to_initials (first, position) if first:find (',', 1, true) then return first; -- commas not allowed; abandon end local name, suffix = mw.ustring.match (first, "^(%u+) ([%dJS][%drndth]+)$"); if not name then -- if not initials and a suffix name = mw.ustring.match (first, "^(%u+)$"); -- is it just initials? end if name then -- if first is initials with or without suffix if 3 > mw.ustring.len (name) then -- if one or two initials if suffix then -- if there is a suffix if is_suffix (suffix) then -- is it legitimate? return first; -- one or two initials and a valid suffix so nothing to do else add_vanc_error (cfg.err_msg_supl.suffix, position); -- one or two initials with invalid suffix so error message return first; -- and return first unmolested end else return first; -- one or two initials without suffix; nothing to do end end end -- if here then name has 3 or more uppercase letters so treat them as a word local initials_t, names_t = {}, {}; -- tables to hold name parts and initials local i = 1; -- counter for number of initials names_t = mw.text.split (first, '[%s%-]+'); -- split into a sequence of names and possible suffix while names_t[i] do -- loop through the sequence if 1 < i and names_t[i]:match ('[%dJS][%drndth]+%.?$') then -- if not the first name, and looks like a suffix (may have trailing dot) names_t[i] = names_t[i]:gsub ('%.', ''); -- remove terminal dot if present if is_suffix (names_t[i]) then -- if a legitimate suffix table.insert (initials_t, ' ' .. names_t[i]); -- add a separator space, insert at end of initials sequence break; -- and done because suffix must fall at the end of a name end -- no error message if not a suffix; possibly because of Romanization end if 3 > i then table.insert (initials_t, mw.ustring.sub (names_t[i], 1, 1)); -- insert the initial at end of initials sequence end i = i + 1; -- bump the counter end return table.concat (initials_t); -- Vancouver format does not include spaces. end --[[--------------------------< I N T E R W I K I _ P R E F I X E N _ G E T >---------------------------------- extract interwiki prefixen from <value>. Returns two one or two values: false – no prefixen nil – prefix exists but not recognized project prefix, language prefix – when value has either of: :<project>:<language>:<article> :<language>:<project>:<article> project prefix, nil – when <value> has only a known single-letter prefix nil, language prefix – when <value> has only a known language prefix accepts single-letter project prefixen: 'd' (wikidata), 's' (wikisource), and 'w' (wikipedia) prefixes; at this writing, the other single-letter prefixen (b (wikibook), c (commons), m (meta), n (wikinews), q (wikiquote), and v (wikiversity)) are not supported. ]] local function interwiki_prefixen_get (value, is_link) if not value:find (':%l+:') then -- if no prefix return false; -- abandon; boolean here to distinguish from nil fail returns later end local prefix_patterns_linked_t = { -- sequence of valid interwiki and inter project prefixen '^%[%[:([dsw]):(%l%l+):', -- wikilinked; project and language prefixes '^%[%[:(%l%l+):([dsw]):', -- wikilinked; language and project prefixes '^%[%[:([dsw]):', -- wikilinked; project prefix '^%[%[:(%l%l+):', -- wikilinked; language prefix } local prefix_patterns_unlinked_t = { -- sequence of valid interwiki and inter project prefixen '^:([dsw]):(%l%l+):', -- project and language prefixes '^:(%l%l+):([dsw]):', -- language and project prefixes '^:([dsw]):', -- project prefix '^:(%l%l+):', -- language prefix } local cap1, cap2; for _, pattern in ipairs ((is_link and prefix_patterns_linked_t) or prefix_patterns_unlinked_t) do cap1, cap2 = value:match (pattern); if cap1 then break; -- found a match so stop looking end end if cap1 and cap2 then -- when both then :project:language: or :language:project: (both forms allowed) if 1 == #cap1 then -- length == 1 then :project:language: if cfg.inter_wiki_map[cap2] then -- is language prefix in the interwiki map? return cap1, cap2; -- return interwiki project and interwiki language end else -- here when :language:project: if cfg.inter_wiki_map[cap1] then -- is language prefix in the interwiki map? return cap2, cap1; -- return interwiki project and interwiki language end end return nil; -- unknown interwiki language elseif not (cap1 or cap2) then -- both are nil? return nil; -- we got something that looks like a project prefix but isn't; return fail elseif 1 == #cap1 then -- here when one capture return cap1, nil; -- length is 1 so return project, nil language else -- here when one capture and its length it more than 1 if cfg.inter_wiki_map[cap1] then -- is language prefix in the interwiki map? return nil, cap1; -- return nil project, language end end end --[[--------------------------< L I S T _ P E O P L E >-------------------------- Formats a list of people (authors, contributors, editors, interviewers, translators) names in the list will be linked when |<name>-link= has a value |<name>-mask- does NOT have a value; masked names are presumed to have been rendered previously so should have been linked there when |<name>-mask=0, the associated name is not rendered ]] local function list_people (control, people, etal) local sep; local namesep; local format = control.format; local maximum = control.maximum; local name_list = {}; if 'vanc' == format then -- Vancouver-like name styling? sep = cfg.presentation['sep_nl_vanc']; -- name-list separator between names is a comma namesep = cfg.presentation['sep_name_vanc']; -- last/first separator is a space else sep = cfg.presentation['sep_nl']; -- name-list separator between names is a semicolon namesep = cfg.presentation['sep_name']; -- last/first separator is <comma><space> end if sep:sub (-1, -1) ~= " " then sep = sep .. " " end if utilities.is_set (maximum) and maximum < 1 then return "", 0; end -- returned 0 is for EditorCount; not used for other names for i, person in ipairs (people) do if utilities.is_set (person.last) then local mask = person.mask; local one; local sep_one = sep; if utilities.is_set (maximum) and i > maximum then etal = true; break; end if mask then local n = tonumber (mask); -- convert to a number if it can be converted; nil else if n then one = 0 ~= n and string.rep("&mdash;", n) or nil; -- make a string of (n > 0) mdashes, nil else, to replace name person.link = nil; -- don't create link to name if name is replaces with mdash string or has been set nil else one = mask; -- replace name with mask text (must include name-list separator) sep_one = " "; -- modify name-list separator end else one = person.last; -- get surname local first = person.first -- get given name if utilities.is_set (first) then if ("vanc" == format) then -- if Vancouver format one = one:gsub ('%.', ''); -- remove periods from surnames (http://www.ncbi.nlm.nih.gov/books/NBK7271/box/A35029/) if not person.corporate and is_good_vanc_name (one, first, nil, i) then -- and name is all Latin characters; corporate authors not tested first = reduce_to_initials (first, i); -- attempt to convert first name(s) to initials end end one = one .. namesep .. first; end end if utilities.is_set (person.link) then one = utilities.make_wikilink (person.link, one); -- link author/editor end if one then -- if <one> has a value (name, mdash replacement, or mask text replacement) local proj, tag = interwiki_prefixen_get (one, true); -- get the interwiki prefixen if present if 'w' == proj and ('Wikipedia' == mw.site.namespaces.Project['name']) then proj = nil; -- for stuff like :w:de:<article>, :w is unnecessary TODO: maint cat? end if proj then proj = ({['d'] = 'Wikidata', ['s'] = 'Wikisource', ['w'] = 'Wikipedia'})[proj]; -- :w (wikipedia) for linking from a non-wikipedia project if proj then one = one .. utilities.wrap_style ('interproj', proj); -- add resized leading space, brackets, static text, language name tag = nil; -- unset; don't do both project and language end end if tag == cfg.this_wiki_code then tag = nil; -- stuff like :en:<article> at en.wiki is pointless TODO: maint cat? end if tag then local lang = cfg.lang_tag_remap[tag] or cfg.mw_languages_by_tag_t[tag]; if lang then -- error messaging done in extract_names() where we know parameter names one = one .. utilities.wrap_style ('interwiki', lang); -- add resized leading space, brackets, static text, language name end end table.insert (name_list, one); -- add it to the list of names table.insert (name_list, sep_one); -- add the proper name-list separator end end end local count = #name_list / 2; -- (number of names + number of separators) divided by 2 if 0 < count then if 1 < count and not etal then if 'amp' == format then name_list[#name_list-2] = " & "; -- replace last separator with ampersand text elseif 'and' == format then if 2 == count then name_list[#name_list-2] = cfg.presentation.sep_nl_and; -- replace last separator with 'and' text else name_list[#name_list-2] = cfg.presentation.sep_nl_end; -- replace last separator with '(sep) and' text end end end name_list[#name_list] = nil; -- erase the last separator end local result = table.concat (name_list); -- construct list if etal and utilities.is_set (result) then -- etal may be set by |display-authors=etal but we might not have a last-first list result = result .. sep .. cfg.messages['et al']; -- we've got a last-first list and etal so add et al. end return result, count; -- return name-list string and count of number of names (count used for editor names only) end --[[--------------------< M A K E _ C I T E R E F _ I D >----------------------- Generates a CITEREF anchor ID if we have at least one name or a date. Otherwise returns an empty string. namelist is one of the contributor-, author-, or editor-name lists chosen in that order. year is Year or anchor_year. ]] local function make_citeref_id (namelist, year) local names={}; -- a table for the one to four names and year for i,v in ipairs (namelist) do -- loop through the list and take up to the first four last names names[i] = v.last if i == 4 then break end -- if four then done end table.insert (names, year); -- add the year at the end local id = table.concat(names); -- concatenate names and year for CITEREF id if utilities.is_set (id) then -- if concatenation is not an empty string return "CITEREF" .. id; -- add the CITEREF portion else return ''; -- return an empty string; no reason to include CITEREF id in this citation end end --[[--------------------------< C I T E _ C L A S S _A T T R I B U T E _M A K E >------------------------------ construct <cite> tag class attribute for this citation. <cite_class> – config.CitationClass from calling template <mode> – value from |mode= parameter ]] local function cite_class_attribute_make (cite_class, mode) local class_t = {}; table.insert (class_t, 'citation'); -- required for blue highlight if 'citation' ~= cite_class then table.insert (class_t, cite_class); -- identify this template for user css table.insert (class_t, utilities.is_set (mode) and mode or 'cs1'); -- identify the citation style for user css or javascript else table.insert (class_t, utilities.is_set (mode) and mode or 'cs2'); -- identify the citation style for user css or javascript end for _, prop_key in ipairs (z.prop_keys_t) do table.insert (class_t, prop_key); -- identify various properties for user css or javascript end return table.concat (class_t, ' '); -- make a big string and done end --[[---------------------< N A M E _ H A S _ E T A L >-------------------------- Evaluates the content of name parameters (author, editor, etc.) for variations on the theme of et al. If found, the et al. is removed, a flag is set to true and the function returns the modified name and the flag. This function never sets the flag to false but returns its previous state because it may have been set by previous passes through this function or by the associated |display-<names>=etal parameter ]] local function name_has_etal (name, etal, nocat, param) if utilities.is_set (name) then -- name can be nil in which case just return local patterns = cfg.et_al_patterns; -- get patterns from configuration for _, pattern in ipairs (patterns) do -- loop through all of the patterns if name:match (pattern) then -- if this 'et al' pattern is found in name name = name:gsub (pattern, ''); -- remove the offending text etal = true; -- set flag (may have been set previously here or by |display-<names>=etal) if not nocat then -- no categorization for |vauthors= utilities.set_message ('err_etal', {param}); -- and set an error if not added end end end end return name, etal; end --[[---------------------< N A M E _ I S _ N U M E R I C >---------------------- Add an error message and category when <name> parameter value does not contain letters. Add a maintenance category when <name> parameter value has numeric characters mixed with characters that are not numeric characters; could be letters and/or punctuation characters. This function will only emit one error and one maint message for the current template. Does not emit both error and maint messages/categories for the same parameter value. ]] local function name_is_numeric (name, name_alias, list_name) local patterns = { '^%D+%d', -- <name> must have digits preceded by other characters '^%D*%d+%D+', -- <name> must have digits followed by other characters } if not added_numeric_name_errs and mw.ustring.match (name, '^[%A]+$') then -- if we have not already set an error message and <name> does not have any alpha characters utilities.set_message ('err_numeric_names', name_alias); -- add an error message added_numeric_name_errs = true; -- set the flag so we emit only one error message return; -- when here no point in further testing; abandon end if not added_numeric_name_maint then -- if we have already set a maint message for _, pattern in ipairs (patterns) do -- spin through list of patterns if mw.ustring.match (name, pattern) then -- digits preceded or followed by anything but digits; %D+ includes punctuation utilities.set_message ('maint_numeric_names', cfg.special_case_translation [list_name]); -- add a maint cat for this template added_numeric_name_maint = true; -- set the flag so we emit only one maint message return; -- when here no point in further testing; abandon end end end end --[[-----------------< N A M E _ H A S _ M U L T _ N A M E S >------------------ Evaluates the content of last/surname (authors etc.) parameters for multiple names. Multiple names are indicated if there is more than one comma or any "unescaped" semicolons. Escaped semicolons are ones used as part of selected HTML entities. If the condition is met, the function adds the multiple name maintenance category. Same test for first except that commas should not appear in given names (MOS:JR says that the generational suffix does not take a separator character). Titles, degrees, postnominals, affiliations, all normally comma separated don't belong in a citation. <name> – name parameter value <list_name> – AuthorList, EditorList, etc <limit> – number of allowed commas; 1 (default) for surnames; 0 for given names returns nothing ]] local function name_has_mult_names (name, list_name, limit) local _, commas, semicolons, nbsps; limit = limit and limit or 1; if utilities.is_set (name) then _, commas = name:gsub (',', ''); -- count the number of commas _, semicolons = name:gsub (';', ''); -- count the number of semicolons -- nbsps probably should be its own separate count rather than merged in -- some way with semicolons because Lua patterns do not support the -- grouping operator that regex does, which means there is no way to add -- more entities to escape except by adding more counts with the new -- entities _, nbsps = name:gsub ('&nbsp;',''); -- count nbsps -- There is exactly 1 semicolon per &nbsp; entity, so subtract nbsps -- from semicolons to 'escape' them. If additional entities are added, -- they also can be subtracted. if limit < commas or 0 < (semicolons - nbsps) then utilities.set_message ('maint_mult_names', cfg.special_case_translation [list_name]); -- add a maint message end end end --[=[-------------------------< I S _ G E N E R I C >---------------------------------------------------------- Compares values assigned to various parameters according to the string provided as <item> in the function call. <item> can have on of two values: 'generic_names' – for name-holding parameters: |last=, |first=, |editor-last=, etc 'generic_titles' – for |title= There are two types of generic tests. The 'accept' tests look for a pattern that should not be rejected by the 'reject' test. For example, |author=[[John Smith (author)|Smith, John]] would be rejected by the 'author' reject test. But piped wikilinks with 'author' disambiguation should not be rejected so the 'accept' test prevents that from happening. Accept tests are always performed before reject tests. Each of the 'accept' and 'reject' sequence tables hold tables for en.wiki (['en']) and local.wiki (['local']) that each can hold a test sequence table The sequence table holds, at index [1], a test pattern, and, at index [2], a boolean control value. The control value tells string.find() or mw.ustring.find() to do plain-text search (true) or a pattern search (false). The intent of all this complexity is to make these searches as fast as possible so that we don't run out of processing time on very large articles. Returns true when a reject test finds the pattern or string false when an accept test finds the pattern or string nil else ]=] local function is_generic (item, value, wiki) local test_val; local str_lower = { -- use string.lower() for en.wiki (['en']) and use mw.ustring.lower() or local.wiki (['local']) ['en'] = string.lower, ['local'] = mw.ustring.lower, } local str_find = { -- use string.find() for en.wiki (['en']) and use mw.ustring.find() or local.wiki (['local']) ['en'] = string.find, ['local'] = mw.ustring.find, } local function test (val, test_t, wiki) -- local function to do the testing; <wiki> selects lower() and find() functions val = test_t[2] and str_lower[wiki](value) or val; -- when <test_t[2]> set to 'true', plaintext search using lowercase value return str_find[wiki] (val, test_t[1], 1, test_t[2]); -- return nil when not found or matched end local test_types_t = {'accept', 'reject'}; -- test accept patterns first, then reject patterns local wikis_t = {'en', 'local'}; -- do tests for each of these keys; en.wiki first, local.wiki second for _, test_type in ipairs (test_types_t) do -- for each test type for _, generic_value in pairs (cfg.special_case_translation[item][test_type]) do -- spin through the list of generic value fragments to accept or reject for _, wiki in ipairs (wikis_t) do if generic_value[wiki] then if test (value, generic_value[wiki], wiki) then -- go do the test return ('reject' == test_type); -- param value rejected, return true; false else end end end end end end --[[--------------------------< N A M E _ I S _ G E N E R I C >------------------------------------------------ calls is_generic() to determine if <name> is a 'generic name' listed in cfg.generic_names; <name_alias> is the parameter name used in error messaging ]] local function name_is_generic (name, name_alias) if not added_generic_name_errs and is_generic ('generic_names', name) then utilities.set_message ('err_generic_name', name_alias); -- set an error message added_generic_name_errs = true; end end --[[--------------------------< N A M E _ C H E C K S >-------------------------------------------------------- This function calls various name checking functions used to validate the content of the various name-holding parameters. ]] local function name_checks (last, first, list_name, last_alias, first_alias) local accept_name; if utilities.is_set (last) then last, accept_name = utilities.has_accept_as_written (last); -- remove accept-this-as-written markup when it wraps all of <last> if not accept_name then -- <last> not wrapped in accept-as-written markup name_has_mult_names (last, list_name); -- check for multiple names in the parameter name_is_numeric (last, last_alias, list_name); -- check for names that have no letters or are a mix of digits and other characters name_is_generic (last, last_alias); -- check for names found in the generic names list end end if utilities.is_set (first) then first, accept_name = utilities.has_accept_as_written (first); -- remove accept-this-as-written markup when it wraps all of <first> if not accept_name then -- <first> not wrapped in accept-as-written markup name_has_mult_names (first, list_name, 0); -- check for multiple names in the parameter; 0 is number of allowed commas in a given name name_is_numeric (first, first_alias, list_name); -- check for names that have no letters or are a mix of digits and other characters name_is_generic (first, first_alias); -- check for names found in the generic names list end local wl_type, D = utilities.is_wikilink (first); if 0 ~= wl_type then first = D; utilities.set_message ('err_bad_paramlink', first_alias); end end return last, first; -- done end --[[----------------------< E X T R A C T _ N A M E S >------------------------- Gets name list from the input arguments Searches through args in sequential order to find |lastn= and |firstn= parameters (or their aliases), and their matching link and mask parameters. Stops searching when both |lastn= and |firstn= are not found in args after two sequential attempts: found |last1=, |last2=, and |last3= but doesn't find |last4= and |last5= then the search is done. This function emits an error message when there is a |firstn= without a matching |lastn=. When there are 'holes' in the list of last names, |last1= and |last3= are present but |last2= is missing, an error message is emitted. |lastn= is not required to have a matching |firstn=. When an author or editor parameter contains some form of 'et al.', the 'et al.' is stripped from the parameter and a flag (etal) returned that will cause list_people() to add the static 'et al.' text from Module:Citation/CS1/Configuration. This keeps 'et al.' out of the template's metadata. When this occurs, an error is emitted. ]] local function extract_names(args, list_name) local names = {}; -- table of names local last; -- individual name components local first; local link; local mask; local i = 1; -- loop counter/indexer local n = 1; -- output table indexer local count = 0; -- used to count the number of times we haven't found a |last= (or alias for authors, |editor-last or alias for editors) local etal = false; -- return value set to true when we find some form of et al. in an author parameter local last_alias, first_alias, link_alias; -- selected parameter aliases used in error messaging while true do last, last_alias = utilities.select_one ( args, cfg.aliases[list_name .. '-Last'], 'err_redundant_parameters', i ); -- search through args for name components beginning at 1 first, first_alias = utilities.select_one ( args, cfg.aliases[list_name .. '-First'], 'err_redundant_parameters', i ); link, link_alias = utilities.select_one ( args, cfg.aliases[list_name .. '-Link'], 'err_redundant_parameters', i ); mask = utilities.select_one ( args, cfg.aliases[list_name .. '-Mask'], 'err_redundant_parameters', i ); if last then -- error check |lastn= alias for unknown interwiki link prefix; done here because this is where we have the parameter name local project, language = interwiki_prefixen_get (last, true); -- true because we expect interwiki links in |lastn= to be wikilinked if nil == project and nil == language then -- when both are nil utilities.set_message ('err_bad_paramlink', last_alias); -- not known, emit an error message -- TODO: err_bad_interwiki? last = utilities.remove_wiki_link (last); -- remove wikilink markup; show display value only end end if link then -- error check |linkn= alias for unknown interwiki link prefix local project, language = interwiki_prefixen_get (link, false); -- false because wiki links in |author-linkn= is an error if nil == project and nil == language then -- when both are nil utilities.set_message ('err_bad_paramlink', link_alias); -- not known, emit an error message -- TODO: err_bad_interwiki? link = nil; -- unset so we don't link link_alias = nil; end end last, etal = name_has_etal (last, etal, false, last_alias); -- find and remove variations on et al. first, etal = name_has_etal (first, etal, false, first_alias); -- find and remove variations on et al. last, first = name_checks (last, first, list_name, last_alias, first_alias); -- multiple names, extraneous annotation, etc. checks if first and not last then -- if there is a firstn without a matching lastn local alias = first_alias:find ('given', 1, true) and 'given' or 'first'; -- get first or given form of the alias utilities.set_message ('err_first_missing_last', { first_alias, -- param name of alias missing its mate first_alias:gsub (alias, {['first'] = 'last', ['given'] = 'surname'}), -- make param name appropriate to the alias form }); -- add this error message elseif not first and not last then -- if both firstn and lastn aren't found, are we done? count = count + 1; -- number of times we haven't found last and first if 2 <= count then -- two missing names and we give up break; -- normal exit or there is a two-name hole in the list; can't tell which end else -- we have last with or without a first local result; link = link_title_ok (link, link_alias, last, last_alias); -- check for improper wiki-markup if first then link = link_title_ok (link, link_alias, first, first_alias); -- check for improper wiki-markup end names[n] = {last = last, first = first, link = link, mask = mask, corporate = false}; -- add this name to our names list (corporate for |vauthors= only) n = n + 1; -- point to next location in the names table if 1 == count then -- if the previous name was missing utilities.set_message ('err_missing_name', {list_name:match ("(%w+)List"):lower(), i - 1}); -- add this error message end count = 0; -- reset the counter, we're looking for two consecutive missing names end i = i + 1; -- point to next args location end return names, etal; -- all done, return our list of names and the etal flag end --[[--------------------------< N A M E _ T A G _ G E T >------------------------------------------------------ attempt to decode |language=<lang_param> and return language name and matching tag; nil else. This function looks for: <lang_param> as a tag in cfg.lang_tag_remap{} <lang_param> as a name in cfg.lang_name_remap{} <lang_param> as a name in cfg.mw_languages_by_name_t <lang_param> as a tag in cfg.mw_languages_by_tag_t when those fail, presume that <lang_param> is an IETF-like tag that MediaWiki does not recognize. Strip all script, region, variant, whatever subtags from <lang_param> to leave just a two or three character language tag and look for the new <lang_param> in cfg.mw_languages_by_tag_t{} on success, returns name (in properly capitalized form) and matching tag (in lowercase); on failure returns nil ]] local function name_tag_get (lang_param) local lang_param_lc = mw.ustring.lower (lang_param); -- use lowercase as an index into the various tables local name; local tag; name = cfg.lang_tag_remap[lang_param_lc]; -- assume <lang_param_lc> is a tag; attempt to get remapped language name if name then -- when <name>, <lang_param> is a tag for a remapped language name if cfg.lang_name_remap[name:lower()][2] ~= lang_param_lc then utilities.set_message ('maint_unknown_lang'); -- add maint category if not already added return name, cfg.lang_name_remap[name:lower()][2]; -- so return name and tag from lang_name_remap[name]; special case to xlate sr-ec and sr-el to sr-cyrl and sr-latn end return name, lang_param_lc; -- so return <name> from remap and <lang_param_lc> end tag = lang_param_lc:match ('^(%a%a%a?)%-.*'); -- still assuming that <lang_param_lc> is a tag; strip script, region, variant subtags name = cfg.lang_tag_remap[tag]; -- attempt to get remapped language name with language subtag only if name then -- when <name>, <tag> is a tag for a remapped language name return name, tag; -- so return <name> from remap and <tag> end if cfg.lang_name_remap[lang_param_lc] then -- not a remapped tag, assume <lang_param_lc> is a name; attempt to get remapped language tag return cfg.lang_name_remap[lang_param_lc][1], cfg.lang_name_remap[lang_param_lc][2]; -- for this <lang_param_lc>, return a (possibly) new name and appropriate tag end name = cfg.mw_languages_by_tag_t[lang_param_lc]; -- assume that <lang_param_lc> is a tag; attempt to get its matching language name if name then return name, lang_param_lc; -- <lang_param_lc> is a tag so return it and <name> end tag = cfg.mw_languages_by_name_t[lang_param_lc]; -- assume that <lang_param_lc> is a language name; attempt to get its matching tag if tag then return cfg.mw_languages_by_tag_t[tag], tag; -- <lang_param_lc> is a name so return the name from the table and <tag> end tag = lang_param_lc:match ('^(%a%a%a?)%-.*'); -- is <lang_param_lc> an IETF-like tag that MediaWiki doesn't recognize? <tag> gets the language subtag; nil else if tag then name = cfg.mw_languages_by_tag_t[tag]; -- attempt to get a language name using the shortened <tag> if name then return name, tag; -- <lang_param_lc> is an unrecognized IETF-like tag so return <name> and language subtag end end end --[[-------------------< L A N G U A G E _ P A R A M E T E R >------------------ Gets language name from a provided two- or three-character ISO 639 code. If a code is recognized by MediaWiki, use the returned name; if not, then use the value that was provided with the language parameter. When |language= contains a recognized language (either code or name), the page is assigned to the category for that code: Category:Norwegian-language sources (no). For valid three-character code languages, the page is assigned to the single category for '639-2' codes: Category:CS1 ISO 639-2 language sources. Languages that are the same as the local wiki are not categorized. MediaWiki does not recognize three-character equivalents of two-character codes: code 'ar' is recognized but code 'ara' is not. This function supports multiple languages in the form |language=nb, French, th where the language names or codes are separated from each other by commas with optional space characters. ]] local function language_parameter (lang) local tag; -- some form of IETF-like language tag; language subtag with optional region, sript, vatiant, etc subtags local lang_subtag; -- ve populates |language= with mostly unecessary region subtags the MediaWiki does not recognize; this is the base language subtag local name; -- the language name local language_list = {}; -- table of language names to be rendered local names_t = {}; -- table made from the value assigned to |language= local this_wiki_name = mw.language.fetchLanguageName (cfg.this_wiki_code, cfg.this_wiki_code); -- get this wiki's language name names_t = mw.text.split (lang, '%s*,%s*'); -- names should be a comma separated list for _, lang in ipairs (names_t) do -- reuse lang here because we don't yet know if lang is a language name or a language tag local fromEnglishToCode = { -- костыль для РУВИКИ: замена распространённых англоназваний на коды, в следующей итерации использовать Module:Language. ['Arabic'] = 'ar', ['Azerbaijani'] = 'az', ['Belarusian'] = 'be', ['Bulgarian'] = 'bg', ['Czech'] = 'cs', ['Danish'] = 'da', ['German'] = 'de', ['Greek'] = 'el', ['Spanish'] = 'es', ['English'] = 'en', ['Finnish'] = 'fi', ['French'] = 'fr', ['Hebrew'] = 'he', ['Croatian'] = 'hr', ['Hungarian'] = 'hu', ['Armenian'] = 'hy', ['Indonesian'] = 'id', ['Italian'] = 'it', ['Japanese'] = 'ja', ['Korean'] = 'ko', ['Latin'] = 'la', ['Dutch'] = 'nl', ['Norwegian'] = 'no', ['Polish'] = 'pl', ['Portuguese'] = 'pt', ['Romanian'] = 'ro', ['Russian'] = 'ru', ['Slovenian'] = 'sl', ['Serbian'] = 'sr', ['Swedish'] = 'sv', ['Thai'] = 'th', ['Turkish'] = 'tr', ['Ukrainian'] = 'uk', ['Chinese'] = 'zh', } if fromEnglishToCode[lang] then lang = fromEnglishToCode[lang] end name, tag = name_tag_get (lang); -- attempt to get name/tag pair for <lang>; <name> has proper capitalization; <tag> is lowercase if utilities.is_set (tag) then lang_subtag = tag:gsub ('^(%a%a%a?)%-.*', '%1'); -- for categorization, strip any IETF-like tags from language tag if cfg.this_wiki_code ~= lang_subtag then -- when the language is not the same as this wiki's language if 2 == lang_subtag:len() then -- and is a two-character tag utilities.add_prop_cat ('foreign-lang-source', {name, tag}, lang_subtag); -- categorize it; tag appended to allow for multiple language categorization else -- or is a recognized language (but has a three-character tag) utilities.add_prop_cat ('foreign-lang-source-2', {lang_subtag}, lang_subtag); -- categorize it differently TODO: support multiple three-character tag categories per cs1|2 template? end elseif cfg.local_lang_cat_enable then -- when the language and this wiki's language are the same and categorization is enabled utilities.add_prop_cat ('local-lang-source', {name, lang_subtag}); -- categorize it end else name = lang; -- return whatever <lang> has so that we show something utilities.set_message ('maint_unknown_lang'); -- add maint category if not already added end table.insert (language_list, name); name = ''; -- so we can reuse it end name = utilities.make_sep_list (#language_list, language_list); if (1 == #language_list) and (lang_subtag == cfg.this_wiki_code) then -- when only one language, find lang name in this wiki lang name; for |language=en-us, 'English' in 'American English' return ''; -- if one language and that language is this wiki's return an empty string (no annotation) end return (mw.getCurrentFrame():expandTemplate{ -- РУВИКИ: используем шаблон для отображения языка title= utilities.substitute (cfg.messages ['language'], tag) }); -- otherwise wrap with '(in ...)' --[[ TODO: should only return blank or name rather than full list so we can clean up the bunched parenthetical elements Language, Type, Format ]] end --[[-----------------------< S E T _ C S _ S T Y L E >-------------------------- Gets the default CS style configuration for the given mode. Returns default separator and either postscript as passed in or the default. In CS1, the default postscript and separator are '.'. In CS2, the default postscript is the empty string and the default separator is ','. ]] local function set_cs_style (postscript, mode) if utilities.is_set(postscript) then -- emit a maintenance message if user postscript is the default cs1 postscript -- we catch the opposite case for cs2 in set_style if mode == 'cs1' and postscript == cfg.presentation['ps_' .. mode] then utilities.set_message ('maint_postscript'); end else postscript = cfg.presentation['ps_' .. mode]; end return cfg.presentation['sep_' .. mode], postscript; end --[[--------------------------< S E T _ S T Y L E >----------------------------- Sets the separator and postscript styles. Checks the |mode= first and the #invoke CitationClass second. Removes the postscript if postscript == none. ]] local function set_style (mode, postscript, cite_class) local sep; if 'cs2' == mode then sep, postscript = set_cs_style (postscript, 'cs2'); elseif 'cs1' == mode then sep, postscript = set_cs_style (postscript, 'cs1'); elseif 'citation' == cite_class then sep, postscript = set_cs_style (postscript, 'cs2'); else sep, postscript = set_cs_style (postscript, 'cs1'); end if cfg.keywords_xlate[postscript:lower()] == 'none' then -- emit a maintenance message if user postscript is the default cs2 postscript -- we catch the opposite case for cs1 in set_cs_style if 'cs2' == mode or ('cs1' ~= mode and 'citation' == cite_class) then -- {{citation |title=Title |mode=cs1 |postscript=none}} should not emit maint message utilities.set_message ('maint_postscript'); end postscript = ''; end return sep, postscript end --[=[-------------------------< I S _ P D F >----------------------------------- Determines if a URL has the file extension that is one of the PDF file extensions used by [[MediaWiki:Common.css]] when applying the PDF icon to external links. returns true if file extension is one of the recognized extensions, else false ]=] local function is_pdf (url) return url:match ('%.pdf$') or url:match ('%.PDF$') or url:match ('%.pdf[%?#]') or url:match ('%.PDF[%?#]') or url:match ('%.PDF&#035') or url:match ('%.pdf&#035'); end --[[--------------------------< S T Y L E _ F O R M A T >----------------------- Applies CSS style to |format=, |chapter-format=, etc. Also emits an error message if the format parameter does not have a matching URL parameter. If the format parameter is not set and the URL contains a file extension that is recognized as a PDF document by MediaWiki's commons.css, this code will set the format parameter to (PDF) with the appropriate styling. ]] local function style_format (format, url, fmt_param, url_param) if utilities.is_set (format) then format = utilities.wrap_style ('format', format); -- add leading space, parentheses, resize if not utilities.is_set (url) then utilities.set_message ('err_format_missing_url', {fmt_param, url_param}); -- add an error message end elseif is_pdf (url) then -- format is not set so if URL is a PDF file then format = utilities.wrap_style ('format', 'PDF'); -- set format to PDF else format = ''; -- empty string for concatenation end return format; end --[[---------------------< G E T _ D I S P L A Y _ N A M E S >------------------ Returns a number that defines the number of names displayed for author and editor name lists and a Boolean flag to indicate when et al. should be appended to the name list. When the value assigned to |display-xxxxors= is a number greater than or equal to zero, return the number and the previous state of the 'etal' flag (false by default but may have been set to true if the name list contains some variant of the text 'et al.'). When the value assigned to |display-xxxxors= is the keyword 'etal', return a number that is one greater than the number of authors in the list and set the 'etal' flag true. This will cause the list_people() to display all of the names in the name list followed by 'et al.' In all other cases, returns nil and the previous state of the 'etal' flag. inputs: max: A['DisplayAuthors'] or A['DisplayEditors'], etc; a number or some flavor of etal count: #a or #e list_name: 'authors' or 'editors' etal: author_etal or editor_etal This function sets an error message when |display-xxxxors= value greater than or equal to number of names but not when <max> comes from {{cs1 config}} global settings. When using global settings, <param> is set to the keyword 'cs1 config' which is used to supress the normal error. Error is suppressed because it is to be expected that some citations in an article will have the same or fewer names that the limit specified in {{cs1 config}}. ]] local function get_display_names (max, count, list_name, etal, param) if utilities.is_set (max) then if 'etal' == max:lower():gsub("[ '%.]", '') then -- the :gsub() portion makes 'etal' from a variety of 'et al.' spellings and stylings max = count + 1; -- number of authors + 1 so display all author name plus et al. etal = true; -- overrides value set by extract_names() elseif max:match ('^%d+$') then -- if is a string of numbers max = tonumber (max); -- make it a number if (max >= count) and ('cs1 config' ~= param) then -- error when local |display-xxxxors= value greater than or equal to number of names; not an error when using global setting utilities.set_message ('err_disp_name', {param, max}); -- add error message max = nil; end else -- not a valid keyword or number utilities.set_message ('err_disp_name', {param, max}); -- add error message max = nil; -- unset; as if |display-xxxxors= had not been set end end return max, etal; end --[[----------< E X T R A _ T E X T _ I N _ P A G E _ C H E C K >--------------- Adds error if |page=, |pages=, |quote-page=, |quote-pages= has what appears to be some form of p. or pp. abbreviation in the first characters of the parameter content. check page for extraneous p, p., pp, pp., pg, pg. at start of parameter value: good pattern: '^P[^%.P%l]' matches when page begins PX or P# but not Px where x and X are letters and # is a digit bad pattern: '^[Pp][PpGg]' matches when page begins pp, pP, Pp, PP, pg, pG, Pg, PG ]] local function extra_text_in_page_check (val, name) if not val:match (cfg.vol_iss_pg_patterns.good_ppattern) then for _, pattern in ipairs (cfg.vol_iss_pg_patterns.bad_ppatterns) do -- spin through the selected sequence table of patterns if val:match (pattern) then -- when a match, error so utilities.set_message ('err_extra_text_pages', name); -- add error message return; -- and done end end end end --[[--------------------------< E X T R A _ T E X T _ I N _ V O L _ I S S _ C H E C K >------------------------ Adds error if |volume= or |issue= has what appears to be some form of redundant 'type' indicator. Applies to both; this function looks for issue text in both |issue= and |volume= and looks for volume-like text in |voluem= and |issue=. For |volume=: 'V.', or 'Vol.' (with or without the dot) abbreviations or 'Volume' in the first characters of the parameter content (all case insensitive). 'V' and 'v' (without the dot) are presumed to be roman numerals so are allowed. For |issue=: 'No.', 'I.', 'Iss.' (with or without the dot) abbreviations, or 'Issue' in the first characters of the parameter content (all case insensitive); numero styling: 'n°' with degree sign U+00B0, and № precomposed numero sign U+2116. Single character values ('v', 'i', 'n') allowed when not followed by separator character ('.', ':', '=', or whitespace character) – param values are trimmed of whitespace by MediaWiki before delivered to the module. <val> is |volume= or |issue= parameter value <name> is |volume= or |issue= parameter name for error message <selector> is 'v' for |volume=, 'i' for |issue= sets error message on failure; returns nothing ]] local function extra_text_in_vol_iss_check (val, name, selector) if not utilities.is_set (val) then return; end local handler = 'v' == selector and 'err_extra_text_volume' or 'err_extra_text_issue'; val = val:lower(); -- force parameter value to lower case for _, pattern in ipairs (cfg.vol_iss_pg_patterns.vi_patterns_t) do -- spin through the sequence table of patterns if val:match (pattern) then -- when a match, error so utilities.set_message (handler, name); -- add error message return; -- and done end end end --[=[-------------------------< G E T _ V _ N A M E _ T A B L E >---------------------------------------------- split apart a |vauthors= or |veditors= parameter. This function allows for corporate names, wrapped in doubled parentheses to also have commas; in the old version of the code, the doubled parentheses were included in the rendered citation and in the metadata. Individual author names may be wikilinked |vauthors=Jones AB, [[E. B. White|White EB]], ((Black, Brown, and Co.)) ]=] local function get_v_name_table (vparam, output_table, output_link_table) local name_table = mw.text.split(vparam, "%s*,%s*"); -- names are separated by commas local wl_type, label, link; -- wl_type not used here; just a placeholder local i = 1; while name_table[i] do if name_table[i]:match ('^%(%(.*[^%)][^%)]$') then -- first segment of corporate with one or more commas; this segment has the opening doubled parentheses local name = name_table[i]; i = i + 1; -- bump indexer to next segment while name_table[i] do name = name .. ', ' .. name_table[i]; -- concatenate with previous segments if name_table[i]:match ('^.*%)%)$') then -- if this table member has the closing doubled parentheses break; -- and done reassembling so end i = i + 1; -- bump indexer end table.insert (output_table, name); -- and add corporate name to the output table table.insert (output_link_table, ''); -- no wikilink else wl_type, label, link = utilities.is_wikilink (name_table[i]); -- wl_type is: 0, no wl (text in label variable); 1, [[D]]; 2, [[L|D]] table.insert (output_table, label); -- add this name if 1 == wl_type then table.insert (output_link_table, label); -- simple wikilink [[D]] else table.insert (output_link_table, link); -- no wikilink or [[L|D]]; add this link if there is one, else empty string end end i = i + 1; end return output_table; end --[[--------------------------< P A R S E _ V A U T H O R S _ V E D I T O R S >-------------------------------- This function extracts author / editor names from |vauthors= or |veditors= and finds matching |xxxxor-maskn= and |xxxxor-linkn= in args. It then returns a table of assembled names just as extract_names() does. Author / editor names in |vauthors= or |veditors= must be in Vancouver system style. Corporate or institutional names may sometimes be required and because such names will often fail the is_good_vanc_name() and other format compliance tests, are wrapped in doubled parentheses ((corporate name)) to suppress the format tests. Supports generational suffixes Jr, 2nd, 3rd, 4th–6th. This function sets the Vancouver error when a required comma is missing and when there is a space between an author's initials. ]] local function parse_vauthors_veditors (args, vparam, list_name) local names = {}; -- table of names assembled from |vauthors=, |author-maskn=, |author-linkn= local v_name_table = {}; local v_link_table = {}; -- when name is wikilinked, targets go in this table local etal = false; -- return value set to true when we find some form of et al. vauthors parameter local last, first, link, mask, suffix; local corporate = false; vparam, etal = name_has_etal (vparam, etal, true); -- find and remove variations on et al. do not categorize (do it here because et al. might have a period) v_name_table = get_v_name_table (vparam, v_name_table, v_link_table); -- names are separated by commas for i, v_name in ipairs(v_name_table) do first = ''; -- set to empty string for concatenation and because it may have been set for previous author/editor local accept_name; v_name, accept_name = utilities.has_accept_as_written (v_name); -- remove accept-this-as-written markup when it wraps all of <v_name> if accept_name then last = v_name; corporate = true; -- flag used in list_people() elseif string.find(v_name, "%s") then if v_name:find('[;%.]') then -- look for commonly occurring punctuation characters; add_vanc_error (cfg.err_msg_supl.punctuation, i); end local lastfirstTable = {} lastfirstTable = mw.text.split(v_name, "%s+") first = table.remove(lastfirstTable); -- removes and returns value of last element in table which should be initials or generational suffix if not mw.ustring.match (first, '^%u+$') then -- mw.ustring here so that later we will catch non-Latin characters suffix = first; -- not initials so assume that whatever we got is a generational suffix first = table.remove(lastfirstTable); -- get what should be the initials from the table end last = table.concat(lastfirstTable, ' ') -- returns a string that is the concatenation of all other names that are not initials and generational suffix if not utilities.is_set (last) then first = ''; -- unset last = v_name; -- last empty because something wrong with first add_vanc_error (cfg.err_msg_supl.name, i); end if mw.ustring.match (last, '%a+%s+%u+%s+%a+') then add_vanc_error (cfg.err_msg_supl['missing comma'], i); -- matches last II last; the case when a comma is missing end if mw.ustring.match (v_name, ' %u %u$') then -- this test is in the wrong place TODO: move or replace with a more appropriate test add_vanc_error (cfg.err_msg_supl.initials, i); -- matches a space between two initials end else last = v_name; -- last name or single corporate name? Doesn't support multiword corporate names? do we need this? end if utilities.is_set (first) then if not mw.ustring.match (first, "^%u?%u$") then -- first shall contain one or two upper-case letters, nothing else add_vanc_error (cfg.err_msg_supl.initials, i); -- too many initials; mixed case initials (which may be ok Romanization); hyphenated initials end is_good_vanc_name (last, first, suffix, i); -- check first and last before restoring the suffix which may have a non-Latin digit if utilities.is_set (suffix) then first = first .. ' ' .. suffix; -- if there was a suffix concatenate with the initials suffix = ''; -- unset so we don't add this suffix to all subsequent names end else if not corporate then is_good_vanc_name (last, '', nil, i); end end link = utilities.select_one ( args, cfg.aliases[list_name .. '-Link'], 'err_redundant_parameters', i ) or v_link_table[i]; mask = utilities.select_one ( args, cfg.aliases[list_name .. '-Mask'], 'err_redundant_parameters', i ); names[i] = {last = last, first = first, link = link, mask = mask, corporate = corporate}; -- add this assembled name to our names list end return names, etal; -- all done, return our list of names end --[[--------------------------< S E L E C T _ A U T H O R _ E D I T O R _ S O U R C E >------------------------ Select one of |authors=, |authorn= / |lastn / firstn=, or |vauthors= as the source of the author name list or select one of |editorn= / editor-lastn= / |editor-firstn= or |veditors= as the source of the editor name list. Only one of these appropriate three will be used. The hierarchy is: |authorn= (and aliases) highest and |authors= lowest; |editorn= (and aliases) highest and |veditors= lowest (support for |editors= withdrawn) When looking for |authorn= / |editorn= parameters, test |xxxxor1= and |xxxxor2= (and all of their aliases); stops after the second test which mimicks the test used in extract_names() when looking for a hole in the author name list. There may be a better way to do this, I just haven't discovered what that way is. Emits an error message when more than one xxxxor name source is provided. In this function, vxxxxors = vauthors or veditors; xxxxors = authors as appropriate. ]] local function select_author_editor_source (vxxxxors, xxxxors, args, list_name) local lastfirst = false; if utilities.select_one ( args, cfg.aliases[list_name .. '-Last'], 'none', 1 ) or -- do this twice in case we have a |first1= without a |last1=; this ... utilities.select_one ( args, cfg.aliases[list_name .. '-First'], 'none', 1 ) or -- ... also catches the case where |first= is used with |vauthors= utilities.select_one ( args, cfg.aliases[list_name .. '-Last'], 'none', 2 ) or utilities.select_one ( args, cfg.aliases[list_name .. '-First'], 'none', 2 ) then lastfirst = true; end if (utilities.is_set (vxxxxors) and true == lastfirst) or -- these are the three error conditions (utilities.is_set (vxxxxors) and utilities.is_set (xxxxors)) or (true == lastfirst and utilities.is_set (xxxxors)) then local err_name; if 'AuthorList' == list_name then -- figure out which name should be used in error message err_name = 'author'; else err_name = 'editor'; end utilities.set_message ('err_redundant_parameters', err_name .. '-name-list parameters'); -- add error message end if true == lastfirst then return 1 end; -- return a number indicating which author name source to use if utilities.is_set (vxxxxors) then return 2 end; if utilities.is_set (xxxxors) then return 3 end; return 1; -- no authors so return 1; this allows missing author name test to run in case there is a first without last end --[[--------------------------< I S _ V A L I D _ P A R A M E T E R _ V A L U E >------------------------------ This function is used to validate a parameter's assigned value for those parameters that have only a limited number of allowable values (yes, y, true, live, dead, etc.). When the parameter value has not been assigned a value (missing or empty in the source template) the function returns the value specified by ret_val. If the parameter value is one of the list of allowed values returns the translated value; else, emits an error message and returns the value specified by ret_val. TODO: explain <invert> ]] local function is_valid_parameter_value (value, name, possible, ret_val, invert) if not utilities.is_set (value) then return ret_val; -- an empty parameter is ok end if (not invert and utilities.in_array (value, possible)) then -- normal; <value> is in <possible> table return cfg.keywords_xlate[value]; -- return translation of parameter keyword elseif invert and not utilities.in_array (value, possible) then -- invert; <value> is not in <possible> table return value; -- return <value> as it is else utilities.set_message ('err_invalid_param_val', {name, value}); -- not an allowed value so add error message return ret_val; end end --[[--------------------------< T E R M I N A T E _ N A M E _ L I S T >---------------------------------------- This function terminates a name list (author, contributor, editor) with a separator character (sepc) and a space when the last character is not a sepc character or when the last three characters are not sepc followed by two closing square brackets (close of a wikilink). When either of these is true, the name_list is terminated with a single space character. ]] local function terminate_name_list (name_list, sepc) if (string.sub (name_list, -3, -1) == sepc .. '. ') then -- if already properly terminated return name_list; -- just return the name list elseif (string.sub (name_list, -1, -1) == sepc) or (string.sub (name_list, -3, -1) == sepc .. ']]') then -- if last name in list ends with sepc char return name_list .. " "; -- don't add another else return name_list .. sepc .. ' '; -- otherwise terminate the name list end end --[[-------------------------< F O R M A T _ V O L U M E _ I S S U E >----------------------------------------- returns the concatenation of the formatted volume and issue (or journal article number) parameters as a single string; or formatted volume or formatted issue, or an empty string if neither are set. ]] local function format_volume_issue (volume, issue, article, cite_class, origin, sepc, lower) if not utilities.is_set (volume) and not utilities.is_set (issue) and not utilities.is_set (article) then return ''; end -- same condition as in format_pages_sheets() local is_journal = 'journal' == cite_class or (utilities.in_array (cite_class, {'citation', 'map', 'interview'}) and 'journal' == origin); local is_numeric_vol = volume and (volume:match ('^[MDCLXVI]+$') or volume:match ('^%d+$')); -- is only uppercase roman numerals or only digits? local is_long_vol = volume and (4 < mw.ustring.len(volume)); -- is |volume= value longer than 4 characters? if volume and (not is_numeric_vol and is_long_vol) then -- when not all digits or Roman numerals, is |volume= longer than 4 characters? utilities.add_prop_cat ('long-vol'); -- yes, add properties cat end if is_journal then -- journal-style formatting local vol = ''; if utilities.is_set (volume) then if is_numeric_vol then -- |volume= value all digits or all uppercase Roman numerals? vol = utilities.substitute (cfg.presentation['vol-bold'], {sepc, volume}); -- render in bold face elseif is_long_vol then -- not all digits or Roman numerals; longer than 4 characters? vol = utilities.substitute (cfg.messages['j-vol'], {sepc, utilities.hyphen_to_dash (volume)}); -- not bold else -- four or fewer characters vol = utilities.substitute (cfg.presentation['vol-bold'], {sepc, utilities.hyphen_to_dash (volume)}); -- bold end end vol = vol .. (utilities.is_set (issue) and utilities.substitute (cfg.messages['j-issue'], issue) or '') vol = vol .. (utilities.is_set (article) and utilities.substitute (cfg.messages['j-article-num'], article) or '') return vol; end if 'podcast' == cite_class and utilities.is_set (issue) then return wrap_msg ('issue', {sepc, issue}, lower); end if 'conference' == cite_class and utilities.is_set (article) then -- |article-number= supported only in journal and conference cites if utilities.is_set (volume) and utilities.is_set (article) then -- both volume and article number return wrap_msg ('vol-art', {sepc, utilities.hyphen_to_dash (volume), article}, lower); elseif utilities.is_set (article) then -- article number alone; when volume alone, handled below return wrap_msg ('art', {sepc, article}, lower); end end -- all other types of citation if utilities.is_set (volume) and utilities.is_set (issue) then return wrap_msg ('vol-no', {sepc, utilities.hyphen_to_dash (volume), issue}, lower); elseif utilities.is_set (volume) then return wrap_msg ('vol', {sepc, utilities.hyphen_to_dash (volume)}, lower); else return wrap_msg ('issue', {sepc, issue}, lower); end end --[[-------------------------< F O R M A T _ P A G E S _ S H E E T S >----------------------------------------- adds static text to one of |page(s)= or |sheet(s)= values and returns it with all of the others set to empty strings. The return order is: page, pages, sheet, sheets Singular has priority over plural when both are provided. ]] local function format_pages_sheets (page, pages, sheet, sheets, cite_class, origin, sepc, nopp, lower) if 'map' == cite_class then -- only cite map supports sheet(s) as in-source locators if utilities.is_set (sheet) then if 'journal' == origin then return '', '', wrap_msg ('j-sheet', sheet, lower), ''; else return '', '', wrap_msg ('sheet', {sepc, sheet}, lower), ''; end elseif utilities.is_set (sheets) then if 'journal' == origin then return '', '', '', wrap_msg ('j-sheets', sheets, lower); else return '', '', '', wrap_msg ('sheets', {sepc, sheets}, lower); end end end local is_journal = 'journal' == cite_class or (utilities.in_array (cite_class, {'citation', 'map', 'interview'}) and 'journal' == origin); if utilities.is_set (page) then if is_journal then return utilities.substitute (cfg.messages['j-page(s)'], page), '', '', ''; elseif not nopp then return utilities.substitute (cfg.messages['p-prefix'], {sepc, page}), '', '', ''; else return utilities.substitute (cfg.messages['nopp'], {sepc, page}), '', '', ''; end elseif utilities.is_set (pages) then if is_journal then return utilities.substitute (cfg.messages['j-page(s)'], pages), '', '', ''; elseif tonumber(pages) ~= nil and not nopp then -- if pages is only digits, assume a single page number return '', utilities.substitute (cfg.messages['p-prefix'], {sepc, pages}), '', ''; elseif not nopp then return '', utilities.substitute (cfg.messages['pp-prefix'], {sepc, pages}), '', ''; else return '', utilities.substitute (cfg.messages['nopp'], {sepc, pages}), '', ''; end end return '', '', '', ''; -- return empty strings end --[[--------------------------< I N S O U R C E _ L O C _ G E T >---------------------------------------------- returns one of the in-source locators: page, pages, or at. If any of these are interwiki links to Wikisource, returns the label portion of the interwiki-link as plain text for use in COinS. This COinS thing is done because here we convert an interwiki-link to an external link and add an icon span around that; get_coins_pages() doesn't know about the span. TODO: should it? TODO: add support for sheet and sheets?; streamline; TODO: make it so that this function returns only one of the three as the single in-source (the return value assigned to a new name)? ]] local function insource_loc_get (page, page_orig, pages, pages_orig, at) local ws_url, ws_label, coins_pages, L; -- for Wikisource interwiki-links; TODO: this corrupts page metadata (span remains in place after cleanup; fix there?) if utilities.is_set (page) then if utilities.is_set (pages) or utilities.is_set (at) then pages = ''; -- unset the others at = ''; end extra_text_in_page_check (page, page_orig); -- emit error message when |page= value begins with what looks like p., pp., etc. ws_url, ws_label, L = wikisource_url_make (page); -- make ws URL from |page= interwiki link; link portion L becomes tooltip label if ws_url then page = external_link (ws_url, ws_label .. '&nbsp;', 'ws link in page'); -- space char after label to move icon away from in-source text; TODO: a better way to do this? page = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], L, page}); coins_pages = ws_label; end elseif utilities.is_set (pages) then if utilities.is_set (at) then at = ''; -- unset end extra_text_in_page_check (pages, pages_orig); -- emit error message when |page= value begins with what looks like p., pp., etc. ws_url, ws_label, L = wikisource_url_make (pages); -- make ws URL from |pages= interwiki link; link portion L becomes tooltip label if ws_url then pages = external_link (ws_url, ws_label .. '&nbsp;', 'ws link in pages'); -- space char after label to move icon away from in-source text; TODO: a better way to do this? pages = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], L, pages}); coins_pages = ws_label; end elseif utilities.is_set (at) then ws_url, ws_label, L = wikisource_url_make (at); -- make ws URL from |at= interwiki link; link portion L becomes tooltip label if ws_url then at = external_link (ws_url, ws_label .. '&nbsp;', 'ws link in at'); -- space char after label to move icon away from in-source text; TODO: a better way to do this? at = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], L, at}); coins_pages = ws_label; end end return page, pages, at, coins_pages; end --[[--------------------------< I S _ U N I Q U E _ A R C H I V E _ U R L >------------------------------------ add error message when |archive-url= value is same as |url= or chapter-url= (or alias...) value ]] local function is_unique_archive_url (archive, url, c_url, source, date) if utilities.is_set (archive) then if archive == url or archive == c_url then utilities.set_message ('err_bad_url', {utilities.wrap_style ('parameter', source)}); -- add error message return '', ''; -- unset |archive-url= and |archive-date= because same as |url= or |chapter-url= end end return archive, date; end --[=[-------------------------< A R C H I V E _ U R L _ C H E C K >-------------------------------------------- Check archive.org URLs to make sure they at least look like they are pointing at valid archives and not to the save snapshot URL or to calendar pages. When the archive URL is 'https://web.archive.org/save/' (or http://...) archive.org saves a snapshot of the target page in the URL. That is something that Wikipedia should not allow unwitting readers to do. When the archive.org URL does not have a complete timestamp, archive.org chooses a snapshot according to its own algorithm or provides a calendar 'search' result. [[WP:ELNO]] discourages links to search results. This function looks at the value assigned to |archive-url= and returns empty strings for |archive-url= and |archive-date= and an error message when: |archive-url= holds an archive.org save command URL |archive-url= is an archive.org URL that does not have a complete timestamp (YYYYMMDDhhmmss 14 digits) in the correct place otherwise returns |archive-url= and |archive-date= There are two mostly compatible archive.org URLs: //web.archive.org/<timestamp>... -- the old form //web.archive.org/web/<timestamp>... -- the new form The old form does not support or map to the new form when it contains a display flag. There are four identified flags ('id_', 'js_', 'cs_', 'im_') but since archive.org ignores others following the same form (two letters and an underscore) we don't check for these specific flags but we do check the form. This function supports a preview mode. When the article is rendered in preview mode, this function may return a modified archive URL: for save command errors, return undated wildcard (/*/) for timestamp errors when the timestamp has a wildcard, return the URL unmodified for timestamp errors when the timestamp does not have a wildcard, return with timestamp limited to six digits plus wildcard (/yyyymm*/) A secondary function is to return an archive-url timestamp from those urls that have them (archive.org and archive.today). The timestamp is used by validation.archive_date_check() to see if the value in |archive-date= matches the timestamp in the archive url. ]=] local function archive_url_check (url, date) local err_msg = ''; -- start with the error message empty local path, timestamp, flag; -- portions of the archive.org URL timestamp = url:match ('//archive.today/(%d%d%d%d%d%d%d%d%d%d%d%d%d%d)/') or -- get timestamp from archive.today urls url:match ('//archive.today/(%d%d%d%d%.%d%d%.%d%d%-%d%d%d%d%d%d)/'); -- this timestamp needs cleanup if timestamp then -- if this was an archive.today url ... return url, date, timestamp:gsub ('[%.%-]', ''); -- return ArchiveURL, ArchiveDate, and timestamp (dots and dashes removed) from |archive-url=, and done -- return ArchiveURL, ArchiveDate, and timestamp from |archive-url=, and done end -- here for archive.org urls if (not url:match('//web%.archive%.org/')) and (not url:match('//liveweb%.archive%.org/')) then -- also deprecated liveweb Wayback machine URL return url, date; -- not an archive.org archive, return ArchiveURL and ArchiveDate end if url:match('//web%.archive%.org/save/') then -- if a save command URL, we don't want to allow saving of the target page err_msg = cfg.err_msg_supl.save; url = url:gsub ('(//web%.archive%.org)/save/', '%1/*/', 1); -- for preview mode: modify ArchiveURL elseif url:match('//liveweb%.archive%.org/') then err_msg = cfg.err_msg_supl.liveweb; else path, timestamp, flag = url:match('//web%.archive%.org/([^%d]*)(%d+)([^/]*)/'); -- split out some of the URL parts for evaluation if not path then -- malformed in some way; pattern did not match err_msg = cfg.err_msg_supl.timestamp; elseif 14 ~= timestamp:len() then -- path and flag optional, must have 14-digit timestamp here err_msg = cfg.err_msg_supl.timestamp; if '*' ~= flag then local replacement = timestamp:match ('^%d%d%d%d%d%d') or timestamp:match ('^%d%d%d%d'); -- get the first 6 (YYYYMM) or first 4 digits (YYYY) if replacement then -- nil if there aren't at least 4 digits (year) replacement = replacement .. string.rep ('0', 14 - replacement:len()); -- year or yearmo (4 or 6 digits) zero-fill to make 14-digit timestamp url=url:gsub ('(//web%.archive%.org/[^%d]*)%d[^/]*', '%1' .. replacement .. '*', 1) -- for preview, modify ts to 14 digits plus splat for calendar display end end elseif utilities.is_set (path) and 'web/' ~= path then -- older archive URLs do not have the extra 'web/' path element err_msg = cfg.err_msg_supl.path; elseif utilities.is_set (flag) and not utilities.is_set (path) then -- flag not allowed with the old form URL (without the 'web/' path element) err_msg = cfg.err_msg_supl.flag; elseif utilities.is_set (flag) and not flag:match ('%a%a_') then -- flag if present must be two alpha characters and underscore (requires 'web/' path element) err_msg = cfg.err_msg_supl.flag; else return url, date, timestamp; -- return ArchiveURL, ArchiveDate, and timestamp from |archive-url= end end -- if here, something not right so utilities.set_message ('err_archive_url', {err_msg}); -- add error message and if is_preview_mode then return url, date, timestamp; -- preview mode so return ArchiveURL, ArchiveDate, and timestamp from |archive-url= else return '', ''; -- return empty strings for ArchiveURL and ArchiveDate end end --[[--------------------------< P L A C E _ C H E C K >-------------------------------------------------------- check |place=, |publication-place=, |location= to see if these params include digits. This function added because many editors misuse location to specify the in-source location (|page(s)= and |at= are supposed to do that) returns the original parameter value without modification; added maint cat when parameter value contains digits ]] local function place_check (param_val) if not utilities.is_set (param_val) then -- parameter empty or omitted return param_val; -- return that empty state end if mw.ustring.find (param_val, '%d') then -- not empty, are there digits in the parameter value utilities.set_message ('maint_location'); -- yep, add maint cat end return param_val; -- and done end --[[--------------------------< I S _ A R C H I V E D _ C O P Y >---------------------------------------------- compares |title= to 'Archived copy' (placeholder added by bots that can't find proper title); if matches, return true; nil else ]] local function is_archived_copy (title) title = mw.ustring.lower(title); -- switch title to lower case if title:find (cfg.special_case_translation.archived_copy.en) then -- if title is 'Archived copy' return true; elseif cfg.special_case_translation.archived_copy['local'] then if mw.ustring.find (title, cfg.special_case_translation.archived_copy['local']) then -- mw.ustring() because might not be Latin script return true; end end end --[[--------------------------< D I S P L A Y _ N A M E S _ S E L E C T >-------------------------------------- for any of the |display-authors=, |display-editors=, etc parameters, select either the local or global setting. When both are present, look at <local_display_names> value. When the value is some sort of 'et al.'string, special handling is required. When {{cs1 config}} has |display-<namelist>= AND this template has |display-<namelist>=etal AND: the number of names specified by <number_of_names> is: greater than the number specified in the global |display-<namelist>= parameter (<global_display_names>) use global |display-<namelist>= parameter value set overridden maint category less than or equal to the number specified in the global |display-<namelist>= parameter use local |display-<namelist>= parameter value The purpose of this function is to prevent categorizing a template that has fewer names than the global setting to keep the etal annotation specified by <local_display_names>. ]] local function display_names_select (global_display_names, local_display_names, param_name, number_of_names, test) if global_display_names and utilities.is_set (local_display_names) then -- when both if 'etal' == local_display_names:lower():gsub("[ '%.]", '') then -- the :gsub() portion makes 'etal' from a variety of 'et al.' spellings and stylings number_of_names = tonumber (number_of_names); -- convert these to numbers for comparison local global_display_names_num = tonumber (global_display_names); -- <global_display_names> not set when parameter value is not digits if number_of_names > global_display_names_num then -- template has more names than global config allows to be displayed? utilities.set_message ('maint_overridden_setting'); -- set a maint message because global is overriding local |display-<namelist>=etal return global_display_names, 'cs1 config'; -- return global with spoof parameter name (for get_display_names()) else return local_display_names, param_name; -- return local because fewer names so let <local_display_names> control end end -- here when <global_display_names> and <local_display_names> both numbers; <global_display_names> controls utilities.set_message ('maint_overridden_setting'); -- set a maint message return global_display_names, 'cs1 config'; -- return global with spoof parameter name (for get_display_names()) end -- here when only one of <global_display_names> or <local_display_names> set if global_display_names then return global_display_names, 'cs1 config'; -- return global with spoof parameter name (for get_display_names()) else return local_display_names, param_name; -- return local end end --[[--------------------------< C I T A T I O N 0 >------------------------------------------------------------ This is the main function doing the majority of the citation formatting. ]] local function citation0( config, args ) --[[ Load Input Parameters The argument_wrapper facilitates the mapping of multiple aliases to single internal variable. ]] local A = argument_wrapper ( args ); local i -- Pick out the relevant fields from the arguments. Different citation templates -- define different field names for the same underlying things. local author_etal; local a = {}; -- authors list from |lastn= / |firstn= pairs or |vauthors= local Authors; local NameListStyle; if cfg.global_cs1_config_t['NameListStyle'] then -- global setting in {{cs1 config}} overrides local |name-list-style= parameter value; nil when empty or assigned value invalid NameListStyle = is_valid_parameter_value (cfg.global_cs1_config_t['NameListStyle'], 'cs1 config: name-list-style', cfg.keywords_lists['name-list-style'], ''); -- error messaging 'param' here is a hoax else NameListStyle = is_valid_parameter_value (A['NameListStyle'], A:ORIGIN('NameListStyle'), cfg.keywords_lists['name-list-style'], ''); end if cfg.global_cs1_config_t['NameListStyle'] and utilities.is_set (A['NameListStyle']) then -- when template has |name-list-style=<something> which global setting has overridden utilities.set_message ('maint_overridden_setting'); -- set a maint message end local Collaboration = A['Collaboration']; do -- to limit scope of selected local selected = select_author_editor_source (A['Vauthors'], A['Authors'], args, 'AuthorList'); if 1 == selected then a, author_etal = extract_names (args, 'AuthorList'); -- fetch author list from |authorn= / |lastn= / |firstn=, |author-linkn=, and |author-maskn= elseif 2 == selected then NameListStyle = 'vanc'; -- override whatever |name-list-style= might be a, author_etal = parse_vauthors_veditors (args, A['Vauthors'], 'AuthorList'); -- fetch author list from |vauthors=, |author-linkn=, and |author-maskn= elseif 3 == selected then Authors = A['Authors']; -- use content of |authors= end if utilities.is_set (Collaboration) then author_etal = true; -- so that |display-authors=etal not required end end local editor_etal; local e = {}; -- editors list from |editor-lastn= / |editor-firstn= pairs or |veditors= do -- to limit scope of selected local selected = select_author_editor_source (A['Veditors'], nil, args, 'EditorList'); -- support for |editors= withdrawn if 1 == selected then e, editor_etal = extract_names (args, 'EditorList'); -- fetch editor list from |editorn= / |editor-lastn= / |editor-firstn=, |editor-linkn=, and |editor-maskn= elseif 2 == selected then NameListStyle = 'vanc'; -- override whatever |name-list-style= might be e, editor_etal = parse_vauthors_veditors (args, args.veditors, 'EditorList'); -- fetch editor list from |veditors=, |editor-linkn=, and |editor-maskn= end end local Chapter = A['Chapter']; -- done here so that we have access to |contribution= from |chapter= aliases local Chapter_origin = A:ORIGIN ('Chapter'); local Contribution; -- because contribution is required for contributor(s) if 'contribution' == Chapter_origin then Contribution = Chapter; -- get the name of the contribution end local c = {}; -- contributors list from |contributor-lastn= / contributor-firstn= pairs if utilities.in_array (config.CitationClass, {"book", "citation"}) and not utilities.is_set (A['Periodical']) then -- |contributor= and |contribution= only supported in book cites c = extract_names (args, 'ContributorList'); -- fetch contributor list from |contributorn= / |contributor-lastn=, -firstn=, -linkn=, -maskn= if 0 < #c then if not utilities.is_set (Contribution) then -- |contributor= requires |contribution= utilities.set_message ('err_contributor_missing_required_param', 'contribution'); -- add missing contribution error message c = {}; -- blank the contributors' table; it is used as a flag later end if 0 == #a then -- |contributor= requires |author= utilities.set_message ('err_contributor_missing_required_param', 'author'); -- add missing author error message c = {}; -- blank the contributors' table; it is used as a flag later end end else -- if not a book cite if utilities.select_one (args, cfg.aliases['ContributorList-Last'], 'err_redundant_parameters', 1 ) then -- are there contributor name list parameters? utilities.set_message ('err_contributor_ignored'); -- add contributor ignored error message end Contribution = nil; -- unset end local Title = A['Title']; local TitleLink = A['TitleLink']; local auto_select = ''; -- default is auto local accept_link; TitleLink, accept_link = utilities.has_accept_as_written (TitleLink, true); -- test for accept-this-as-written markup if (not accept_link) and utilities.in_array (TitleLink, {'none', 'pmc', 'doi'}) then -- check for special keywords auto_select = TitleLink; -- remember selection for later TitleLink = ''; -- treat as if |title-link= would have been empty end TitleLink = link_title_ok (TitleLink, A:ORIGIN ('TitleLink'), Title, 'title'); -- check for wiki-markup in |title-link= or wiki-markup in |title= when |title-link= is set local Section = ''; -- {{cite map}} only; preset to empty string for concatenation if not used if 'map' == config.CitationClass and 'section' == Chapter_origin then Section = A['Chapter']; -- get |section= from |chapter= alias list; |chapter= and the other aliases not supported in {{cite map}} Chapter = ''; -- unset for now; will be reset later from |map= if present end local Periodical = A['Periodical']; local Periodical_origin = A:ORIGIN('Periodical'); local ScriptPeriodical = A['ScriptPeriodical']; local ScriptPeriodical_origin = A:ORIGIN('ScriptPeriodical'); local TransPeriodical = A['TransPeriodical']; local TransPeriodical_origin = A:ORIGIN ('TransPeriodical'); if (utilities.in_array (config.CitationClass, {'book', 'encyclopaedia'}) and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical) or utilities.is_set (TransPeriodical))) then local param; if utilities.is_set (Periodical) then -- get a parameter name from one of these periodical related meta-parameters Periodical = ''; -- unset because not valid {{cite book}} or {{cite encyclopedia}} parameters param = Periodical_origin -- get parameter name for error messaging elseif utilities.is_set (TransPeriodical) then TransPeriodical = ''; -- unset because not valid {{cite book}} or {{cite encyclopedia}} parameters param = TransPeriodical_origin; -- get parameter name for error messaging elseif utilities.is_set (ScriptPeriodical) then ScriptPeriodical = ''; -- unset because not valid {{cite book}} or {{cite encyclopedia}} parameters param = ScriptPeriodical_origin; -- get parameter name for error messaging end if utilities.is_set (param) then -- if we found one utilities.set_message ('err_periodical_ignored', {param}); -- emit an error message end end if utilities.is_set (Periodical) then local i; Periodical, i = utilities.strip_apostrophe_markup (Periodical); -- strip apostrophe markup so that metadata isn't contaminated if i then -- non-zero when markup was stripped so emit an error message utilities.set_message ('err_apostrophe_markup', {Periodical_origin}); end end if 'mailinglist' == config.CitationClass then -- special case for {{cite mailing list}} if utilities.is_set (Periodical) and utilities.is_set (A ['MailingList']) then -- both set emit an error TODO: make a function for this and similar? utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', Periodical_origin) .. cfg.presentation['sep_list_pair'] .. utilities.wrap_style ('parameter', 'mailinglist')}); end Periodical = A ['MailingList']; -- error or no, set Periodical to |mailinglist= value because this template is {{cite mailing list}} Periodical_origin = A:ORIGIN('MailingList'); end -- web and news not tested for now because of -- Wikipedia:Administrators%27_noticeboard#Is_there_a_semi-automated_tool_that_could_fix_these_annoying_"Cite_Web"_errors? if not (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) then -- 'periodical' templates require periodical parameter -- local p = {['journal'] = 'journal', ['magazine'] = 'magazine', ['news'] = 'newspaper', ['web'] = 'website'}; -- for error message local p = {['journal'] = 'journal', ['magazine'] = 'magazine'}; -- for error message if p[config.CitationClass] then utilities.set_message ('err_missing_periodical', {config.CitationClass, p[config.CitationClass]}); end end local Volume; if 'citation' == config.CitationClass then if utilities.is_set (Periodical) then if not utilities.in_array (Periodical_origin, cfg.citation_no_volume_t) then -- {{citation}} does not render |volume= when these parameters are used Volume = A['Volume']; -- but does for all other 'periodicals' end elseif utilities.is_set (ScriptPeriodical) then if 'script-website' ~= ScriptPeriodical_origin then -- {{citation}} does not render volume for |script-website= Volume = A['Volume']; -- but does for all other 'periodicals' end else Volume = A['Volume']; -- and does for non-'periodical' cites end elseif utilities.in_array (config.CitationClass, cfg.templates_using_volume) then -- render |volume= for cs1 according to the configuration settings Volume = A['Volume']; end extra_text_in_vol_iss_check (Volume, A:ORIGIN ('Volume'), 'v'); local Issue; if 'citation' == config.CitationClass then if utilities.is_set (Periodical) and utilities.in_array (Periodical_origin, cfg.citation_issue_t) then -- {{citation}} may render |issue= when these parameters are used Issue = utilities.hyphen_to_dash (A['Issue']); end elseif utilities.in_array (config.CitationClass, cfg.templates_using_issue) then -- conference & map books do not support issue; {{citation}} listed here because included in settings table if not (utilities.in_array (config.CitationClass, {'conference', 'map', 'citation'}) and not (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical))) then Issue = utilities.hyphen_to_dash (A['Issue']); end end local ArticleNumber; if utilities.in_array (config.CitationClass, {'journal', 'conference'}) or ('citation' == config.CitationClass and utilities.is_set (Periodical) and 'journal' == Periodical_origin) then ArticleNumber = A['ArticleNumber']; end extra_text_in_vol_iss_check (Issue, A:ORIGIN ('Issue'), 'i'); local Page; local Pages; local At; local QuotePage; local QuotePages; if not utilities.in_array (config.CitationClass, cfg.templates_not_using_page) then -- TODO: rewrite to emit ignored parameter error message? Page = A['Page']; Pages = utilities.hyphen_to_dash (A['Pages']); At = A['At']; QuotePage = A['QuotePage']; QuotePages = utilities.hyphen_to_dash (A['QuotePages']); end local Edition = A['Edition']; local PublicationPlace = place_check (A['PublicationPlace'], A:ORIGIN('PublicationPlace')); local Place = place_check (A['Place'], A:ORIGIN('Place')); local PublisherName = A['PublisherName']; local PublisherName_origin = A:ORIGIN('PublisherName'); if utilities.is_set (PublisherName) and (cfg.keywords_xlate['none'] ~= PublisherName) then local i = 0; PublisherName, i = utilities.strip_apostrophe_markup (PublisherName); -- strip apostrophe markup so that metadata isn't contaminated; publisher is never italicized if i and (0 < i) then -- non-zero when markup was stripped so emit an error message utilities.set_message ('err_apostrophe_markup', {PublisherName_origin}); end end if ('document' == config.CitationClass) and not utilities.is_set (PublisherName) then utilities.set_message ('err_missing_publisher', {config.CitationClass, 'publisher'}); end local Newsgroup = A['Newsgroup']; -- TODO: strip apostrophe markup? local Newsgroup_origin = A:ORIGIN('Newsgroup'); if 'newsgroup' == config.CitationClass then if utilities.is_set (PublisherName) and (cfg.keywords_xlate['none'] ~= PublisherName) then -- general use parameter |publisher= not allowed in cite newsgroup utilities.set_message ('err_parameter_ignored', {PublisherName_origin}); end PublisherName = nil; -- ensure that this parameter is unset for the time being; will be used again after COinS end local URL = A['URL']; -- TODO: better way to do this for URL, ChapterURL, and MapURL? local UrlAccess = is_valid_parameter_value (A['UrlAccess'], A:ORIGIN('UrlAccess'), cfg.keywords_lists['url-access'], nil); if not utilities.is_set (URL) and utilities.is_set (UrlAccess) then UrlAccess = nil; utilities.set_message ('err_param_access_requires_param', 'url'); end local ChapterURL = A['ChapterURL']; local ChapterUrlAccess = is_valid_parameter_value (A['ChapterUrlAccess'], A:ORIGIN('ChapterUrlAccess'), cfg.keywords_lists['url-access'], nil); if not utilities.is_set (ChapterURL) and utilities.is_set (ChapterUrlAccess) then ChapterUrlAccess = nil; utilities.set_message ('err_param_access_requires_param', {A:ORIGIN('ChapterUrlAccess'):gsub ('%-access', '')}); end local MapUrlAccess = is_valid_parameter_value (A['MapUrlAccess'], A:ORIGIN('MapUrlAccess'), cfg.keywords_lists['url-access'], nil); if not utilities.is_set (A['MapURL']) and utilities.is_set (MapUrlAccess) then MapUrlAccess = nil; utilities.set_message ('err_param_access_requires_param', {'map-url'}); end local this_page = mw.title.getCurrentTitle(); -- also used for COinS and for language local no_tracking_cats = is_valid_parameter_value (A['NoTracking'], A:ORIGIN('NoTracking'), cfg.keywords_lists['yes_true_y'], nil); -- check this page to see if it is in one of the namespaces that cs1 is not supposed to add to the error categories if not utilities.is_set (no_tracking_cats) then -- ignore if we are already not going to categorize this page if cfg.uncategorized_namespaces[this_page.namespace] then -- is this page's namespace id one of the uncategorized namespace ids? no_tracking_cats = "true"; -- set no_tracking_cats end for _, v in ipairs (cfg.uncategorized_subpages) do -- cycle through page name patterns if this_page.text:match (v) then -- test page name against each pattern no_tracking_cats = "true"; -- set no_tracking_cats break; -- bail out if one is found end end end -- no_tracking_cats = "true"; -- выключаем всю категоризацию для РУВИКИ -- check for extra |page=, |pages= or |at= parameters. (also sheet and sheets while we're at it) utilities.select_one (args, {'page', 'p', 'pp', 'pages', 'at', 'sheet', 'sheets'}, 'err_redundant_parameters'); -- this is a dummy call simply to get the error message and category local coins_pages; Page, Pages, At, coins_pages = insource_loc_get (Page, A:ORIGIN('Page'), Pages, A:ORIGIN('Pages'), At); local NoPP = is_valid_parameter_value (A['NoPP'], A:ORIGIN('NoPP'), cfg.keywords_lists['yes_true_y'], nil); if utilities.is_set (PublicationPlace) and utilities.is_set (Place) then -- both |publication-place= and |place= (|location=) allowed if different utilities.add_prop_cat ('location-test'); -- add property cat to evaluate how often PublicationPlace and Place are used together if PublicationPlace == Place then Place = ''; -- unset; don't need both if they are the same end elseif not utilities.is_set (PublicationPlace) and utilities.is_set (Place) then -- when only |place= (|location=) is set ... PublicationPlace = Place; -- promote |place= (|location=) to |publication-place end if PublicationPlace == Place then Place = ''; end -- don't need both if they are the same local URL_origin = A:ORIGIN('URL'); -- get name of parameter that holds URL local ChapterURL_origin = A:ORIGIN('ChapterURL'); -- get name of parameter that holds ChapterURL local ScriptChapter = A['ScriptChapter']; local ScriptChapter_origin = A:ORIGIN ('ScriptChapter'); local Format = A['Format']; local ChapterFormat = A['ChapterFormat']; local TransChapter = A['TransChapter']; local TransChapter_origin = A:ORIGIN ('TransChapter'); local TransTitle = A['TransTitle']; local ScriptTitle = A['ScriptTitle']; --[[ Parameter remapping for cite encyclopedia: When the citation has these parameters: |encyclopedia= and |title= then map |title= to |article= and |encyclopedia= to |title= for rendering |encyclopedia= and |article= then map |encyclopedia= to |title= for rendering |trans-title= maps to |trans-chapter= when |title= is re-mapped |url= maps to |chapter-url= when |title= is remapped All other combinations of |encyclopedia=, |title=, and |article= are not modified ]] local Encyclopedia = A['Encyclopedia']; -- used as a flag by this module and by ~/COinS local ScriptEncyclopedia = A['ScriptEncyclopedia']; local TransEncyclopedia = A['TransEncyclopedia']; if utilities.is_set (Encyclopedia) or utilities.is_set (ScriptEncyclopedia) then -- emit error message when Encyclopedia set but template is other than {{cite encyclopedia}} or {{citation}} if 'encyclopaedia' ~= config.CitationClass and 'citation' ~= config.CitationClass then if utilities.is_set (Encyclopedia) then utilities.set_message ('err_parameter_ignored', {A:ORIGIN ('Encyclopedia')}); else utilities.set_message ('err_parameter_ignored', {A:ORIGIN ('ScriptEncyclopedia')}); end Encyclopedia = nil; -- unset these because not supported by this template ScriptEncyclopedia = nil; TransEncyclopedia = nil; end elseif utilities.is_set (TransEncyclopedia) then utilities.set_message ('err_trans_missing_title', {'encyclopedia'}); end if ('encyclopaedia' == config.CitationClass) or ('citation' == config.CitationClass and utilities.is_set (Encyclopedia)) then if utilities.is_set (Periodical) and utilities.is_set (Encyclopedia) then -- when both parameters set emit an error message; {{citation}} only; Periodical not allowed in {{cite encyclopedia}} utilities.set_message ('err_periodical_ignored', {Periodical_origin}); end if utilities.is_set (Encyclopedia) or utilities.is_set (ScriptEncyclopedia) then Periodical = Encyclopedia; -- error or no, set Periodical to Encyclopedia for rendering; {{citation}} could (not legitimately) have both; use Encyclopedia Periodical_origin = A:ORIGIN ('Encyclopedia'); ScriptPeriodical = ScriptEncyclopedia; ScriptPeriodical_origin = A:ORIGIN ('ScriptEncyclopedia'); if utilities.is_set (Title) or utilities.is_set (ScriptTitle) then if not utilities.is_set (Chapter) then Chapter = Title; -- |encyclopedia= and |title= are set so map |title= params to |article= params for rendering ScriptChapter = ScriptTitle; ScriptChapter_origin = A:ORIGIN('ScriptTitle') TransChapter = TransTitle; ChapterURL = URL; ChapterURL_origin = URL_origin; ChapterUrlAccess = UrlAccess; ChapterFormat = Format; if not utilities.is_set (ChapterURL) and utilities.is_set (TitleLink) then Chapter = utilities.make_wikilink (TitleLink, Chapter); end Title = Periodical; -- now map |encyclopedia= params to |title= params for rendering ScriptTitle = ScriptPeriodical or ''; TransTitle = TransEncyclopedia or ''; Periodical = ''; -- redundant so unset ScriptPeriodical = ''; URL = ''; Format = ''; TitleLink = ''; end elseif utilities.is_set (Chapter) or utilities.is_set (ScriptChapter) then -- |title= not set Title = Periodical; -- |encyclopedia= set and |article= set so map |encyclopedia= to |title= for rendering ScriptTitle = ScriptPeriodical or ''; TransTitle = TransEncyclopedia or ''; Periodical = ''; -- redundant so unset ScriptPeriodical = ''; end end end -- special case for cite techreport. local ID = A['ID']; if (config.CitationClass == "techreport") then -- special case for cite techreport if utilities.is_set (A['Number']) then -- cite techreport uses 'number', which other citations alias to 'issue' if not utilities.is_set (ID) then -- can we use ID for the "number"? ID = A['Number']; -- yes, use it else -- ID has a value so emit error message utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', 'id') .. cfg.presentation['sep_list_pair'] .. utilities.wrap_style ('parameter', 'number')}); end end end -- Account for the oddity that is {{cite conference}}, before generation of COinS data. local ChapterLink -- = A['ChapterLink']; -- deprecated as a parameter but still used internally by cite episode local Conference = A['Conference']; local BookTitle = A['BookTitle']; local TransTitle_origin = A:ORIGIN ('TransTitle'); if 'conference' == config.CitationClass then if utilities.is_set (BookTitle) then Chapter = Title; Chapter_origin = 'title'; -- ChapterLink = TitleLink; -- |chapter-link= is deprecated ChapterURL = URL; ChapterUrlAccess = UrlAccess; ChapterURL_origin = URL_origin; URL_origin = ''; ChapterFormat = Format; TransChapter = TransTitle; TransChapter_origin = TransTitle_origin; Title = BookTitle; Format = ''; -- TitleLink = ''; TransTitle = ''; URL = ''; end elseif 'speech' ~= config.CitationClass then Conference = ''; -- not cite conference or cite speech so make sure this is empty string end -- CS1/2 mode local Mode; if cfg.global_cs1_config_t['Mode'] then -- global setting in {{cs1 config}} overrides local |mode= parameter value; nil when empty or assigned value invalid Mode = is_valid_parameter_value (cfg.global_cs1_config_t['Mode'], 'cs1 config: mode', cfg.keywords_lists['mode'], ''); -- error messaging 'param' here is a hoax else Mode = is_valid_parameter_value (A['Mode'], A:ORIGIN('Mode'), cfg.keywords_lists['mode'], ''); end if cfg.global_cs1_config_t['Mode'] and utilities.is_set (A['Mode']) then -- when template has |mode=<something> which global setting has overridden utilities.set_message ('maint_overridden_setting'); -- set a maint message end -- separator character and postscript local sepc, PostScript = set_style (Mode:lower(), A['PostScript'], config.CitationClass); -- controls capitalization of certain static text local use_lowercase = ( sepc == ',' ); -- cite map oddities local Cartography = ""; local Scale = ""; local Sheet = A['Sheet'] or ''; local Sheets = A['Sheets'] or ''; if config.CitationClass == "map" then if utilities.is_set (Chapter) then --TODO: make a function for this and similar? utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', 'map') .. cfg.presentation['sep_list_pair'] .. utilities.wrap_style ('parameter', Chapter_origin)}); -- add error message end Chapter = A['Map']; Chapter_origin = A:ORIGIN('Map'); ChapterURL = A['MapURL']; ChapterURL_origin = A:ORIGIN('MapURL'); TransChapter = A['TransMap']; ScriptChapter = A['ScriptMap'] ScriptChapter_origin = A:ORIGIN('ScriptMap') ChapterUrlAccess = MapUrlAccess; ChapterFormat = A['MapFormat']; Cartography = A['Cartography']; if utilities.is_set ( Cartography ) then Cartography = sepc .. " " .. wrap_msg ('cartography', Cartography, use_lowercase); end Scale = A['Scale']; if utilities.is_set ( Scale ) then Scale = sepc .. " " .. Scale; end end -- Account for the oddities that are {{cite episode}} and {{cite serial}}, before generation of COinS data. local Series = A['Series']; if 'episode' == config.CitationClass or 'serial' == config.CitationClass then local SeriesLink = A['SeriesLink']; SeriesLink = link_title_ok (SeriesLink, A:ORIGIN ('SeriesLink'), Series, 'series'); -- check for wiki-markup in |series-link= or wiki-markup in |series= when |series-link= is set local Network = A['Network']; local Station = A['Station']; local s, n = {}, {}; -- do common parameters first if utilities.is_set (Network) then table.insert(n, Network); end if utilities.is_set (Station) then table.insert(n, Station); end ID = table.concat(n, sepc .. ' '); if 'episode' == config.CitationClass then -- handle the oddities that are strictly {{cite episode}} local Season = A['Season']; local SeriesNumber = A['SeriesNumber']; if utilities.is_set (Season) and utilities.is_set (SeriesNumber) then -- these are mutually exclusive so if both are set TODO: make a function for this and similar? utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', 'season') .. cfg.presentation['sep_list_pair'] .. utilities.wrap_style ('parameter', 'seriesno')}); -- add error message SeriesNumber = ''; -- unset; prefer |season= over |seriesno= end -- assemble a table of parts concatenated later into Series if utilities.is_set (Season) then table.insert(s, wrap_msg ('season', Season, use_lowercase)); end if utilities.is_set (SeriesNumber) then table.insert(s, wrap_msg ('seriesnum', SeriesNumber, use_lowercase)); end if utilities.is_set (Issue) then table.insert(s, wrap_msg ('episode', Issue, use_lowercase)); end Issue = ''; -- unset because this is not a unique parameter Chapter = Title; -- promote title parameters to chapter ScriptChapter = ScriptTitle; ScriptChapter_origin = A:ORIGIN('ScriptTitle'); ChapterLink = TitleLink; -- alias |episode-link= TransChapter = TransTitle; ChapterURL = URL; ChapterUrlAccess = UrlAccess; ChapterURL_origin = URL_origin; ChapterFormat = Format; Title = Series; -- promote series to title TitleLink = SeriesLink; Series = table.concat(s, sepc .. ' '); -- this is concatenation of season, seriesno, episode number if utilities.is_set (ChapterLink) and not utilities.is_set (ChapterURL) then -- link but not URL Chapter = utilities.make_wikilink (ChapterLink, Chapter); elseif utilities.is_set (ChapterLink) and utilities.is_set (ChapterURL) then -- if both are set, URL links episode; Series = utilities.make_wikilink (ChapterLink, Series); end URL = ''; -- unset TransTitle = ''; ScriptTitle = ''; Format = ''; else -- now oddities that are cite serial Issue = ''; -- unset because this parameter no longer supported by the citation/core version of cite serial Chapter = A['Episode']; -- TODO: make |episode= available to cite episode someday? if utilities.is_set (Series) and utilities.is_set (SeriesLink) then Series = utilities.make_wikilink (SeriesLink, Series); end Series = utilities.wrap_style ('italic-title', Series); -- series is italicized end end -- end of {{cite episode}} stuff -- handle type parameter for those CS1 citations that have default values local TitleType = A['TitleType']; local Degree = A['Degree']; if utilities.in_array (config.CitationClass, {'AV-media-notes', 'document', 'interview', 'mailinglist', 'map', 'podcast', 'pressrelease', 'report', 'speech', 'techreport', 'thesis'}) then TitleType = set_titletype (config.CitationClass, TitleType); if utilities.is_set (Degree) and "Thesis" == TitleType then -- special case for cite thesis TitleType = Degree .. ' ' .. cfg.title_types ['thesis']:lower(); end end if utilities.is_set (TitleType) then -- if type parameter is specified TitleType = utilities.substitute ( cfg.messages['type'], TitleType); -- display it in parentheses -- TODO: Hack on TitleType to fix bunched parentheses problem end -- legacy: promote PublicationDate to Date if neither Date nor Year are set. local Date = A['Date']; local Date_origin; -- to hold the name of parameter promoted to Date; required for date error messaging local PublicationDate = A['PublicationDate']; local Year = A['Year']; if not utilities.is_set (Date) then Date = Year; -- promote Year to Date Year = nil; -- make nil so Year as empty string isn't used for CITEREF if not utilities.is_set (Date) and utilities.is_set (PublicationDate) then -- use PublicationDate when |date= and |year= are not set Date = PublicationDate; -- promote PublicationDate to Date PublicationDate = ''; -- unset, no longer needed Date_origin = A:ORIGIN('PublicationDate'); -- save the name of the promoted parameter else Date_origin = A:ORIGIN('Year'); -- save the name of the promoted parameter end else Date_origin = A:ORIGIN('Date'); -- not a promotion; name required for error messaging end if PublicationDate == Date then PublicationDate = ''; end -- if PublicationDate is same as Date, don't display in rendered citation --[[ Go test all of the date-holding parameters for valid MOS:DATE format and make sure that dates are real dates. This must be done before we do COinS because here is where we get the date used in the metadata. Date validation supporting code is in Module:Citation/CS1/Date_validation ]] local DF = is_valid_parameter_value (A['DF'], A:ORIGIN('DF'), cfg.keywords_lists['df'], ''); if not utilities.is_set (DF) then DF = cfg.global_df; -- local |df= if present overrides global df set by {{use xxx date}} template end local ArchiveURL; local ArchiveDate; local ArchiveFormat = A['ArchiveFormat']; local archive_url_timestamp; -- timestamp from wayback machine url ArchiveURL, ArchiveDate, archive_url_timestamp = archive_url_check (A['ArchiveURL'], A['ArchiveDate']) ArchiveFormat = style_format (ArchiveFormat, ArchiveURL, 'archive-format', 'archive-url'); ArchiveURL, ArchiveDate = is_unique_archive_url (ArchiveURL, URL, ChapterURL, A:ORIGIN('ArchiveURL'), ArchiveDate); -- add error message when URL or ChapterURL == ArchiveURL local AccessDate = A['AccessDate']; local COinS_date = {}; -- holds date info extracted from |date= for the COinS metadata by Module:Date verification local DoiBroken = A['DoiBroken']; local Embargo = A['Embargo']; local anchor_year; -- used in the CITEREF identifier do -- create defined block to contain local variables error_message, date_parameters_list, mismatch local error_message = ''; -- AirDate has been promoted to Date so not necessary to check it local date_parameters_list = { ['access-date'] = {val = AccessDate, name = A:ORIGIN ('AccessDate')}, ['archive-date'] = {val = ArchiveDate, name = A:ORIGIN ('ArchiveDate')}, ['date'] = {val = Date, name = Date_origin}, ['doi-broken-date'] = {val = DoiBroken, name = A:ORIGIN ('DoiBroken')}, ['pmc-embargo-date'] = {val = Embargo, name = A:ORIGIN ('Embargo')}, ['publication-date'] = {val = PublicationDate, name = A:ORIGIN ('PublicationDate')}, ['year'] = {val = Year, name = A:ORIGIN ('Year')}, }; local error_list = {}; anchor_year, Embargo = validation.dates(date_parameters_list, COinS_date, error_list); if utilities.is_set (Year) and utilities.is_set (Date) then -- both |date= and |year= not normally needed; validation.year_date_check (Year, A:ORIGIN ('Year'), Date, A:ORIGIN ('Date'), error_list); end if 0 == #error_list then -- error free dates only; 0 when error_list is empty local modified = false; -- flag if utilities.is_set (DF) then -- if we need to reformat dates modified = validation.reformat_dates (date_parameters_list, DF); -- reformat to DF format, use long month names if appropriate end if true == validation.date_hyphen_to_dash (date_parameters_list) then -- convert hyphens to dashes where appropriate modified = true; utilities.set_message ('maint_date_format'); -- hyphens were converted so add maint category end -- for those wikis that can and want to have English date names translated to the local language; not supported at en.wiki if cfg.date_name_auto_xlate_enable and validation.date_name_xlate (date_parameters_list, cfg.date_digit_auto_xlate_enable ) then utilities.set_message ('maint_date_auto_xlated'); -- add maint cat modified = true; end if modified then -- if the date_parameters_list values were modified AccessDate = date_parameters_list['access-date'].val; -- overwrite date holding parameters with modified values ArchiveDate = date_parameters_list['archive-date'].val; Date = date_parameters_list['date'].val; DoiBroken = date_parameters_list['doi-broken-date'].val; PublicationDate = date_parameters_list['publication-date'].val; end if archive_url_timestamp and utilities.is_set (ArchiveDate) then validation.archive_date_check (ArchiveDate, archive_url_timestamp, DF); -- does YYYYMMDD in archive_url_timestamp match date in ArchiveDate end else utilities.set_message ('err_bad_date', {utilities.make_sep_list (#error_list, error_list)}); -- add this error message end end -- end of do if utilities.in_array (config.CitationClass, {'book', 'encyclopaedia'}) or -- {{cite book}}, {{cite encyclopedia}}; TODO: {{cite conference}} and others? ('citation' == config.CitationClass and utilities.is_set (Encyclopedia)) or -- {{citation}} as an encylopedia citation ('citation' == config.CitationClass and not utilities.is_set (Periodical)) then -- {{citation}} as a book citation if utilities.is_set (PublicationPlace) then if not utilities.is_set (PublisherName) then local date = COinS_date.rftdate and tonumber (COinS_date.rftdate:match ('%d%d%d%d')); -- get year portion of COinS date (because in Arabic numerals); convert string to number if date and (1850 <= date) then -- location has no publisher; if date is 1850 or later utilities.set_message ('maint_location_no_publisher'); -- add maint cat end else -- PublisherName has a value if cfg.keywords_xlate['none'] == PublisherName then -- if that value is 'none' (only for book and encyclopedia citations) PublisherName = ''; -- unset end end end end local ID_list = {}; -- sequence table of rendered identifiers local ID_list_coins = {}; -- table of identifiers and their values from args; key is same as cfg.id_handlers's key local Class = A['Class']; -- arxiv class identifier local ID_support = { {A['ASINTLD'], 'ASIN', 'err_asintld_missing_asin', A:ORIGIN ('ASINTLD')}, {DoiBroken, 'DOI', 'err_doibroken_missing_doi', A:ORIGIN ('DoiBroken')}, {Embargo, 'PMC', 'err_embargo_missing_pmc', A:ORIGIN ('Embargo')}, } ID_list, ID_list_coins = identifiers.identifier_lists_get (args, {DoiBroken = DoiBroken, ASINTLD = A['ASINTLD'], Embargo = Embargo, Class = Class}, ID_support); -- Account for the oddities that are {{cite arxiv}}, {{cite biorxiv}}, {{cite citeseerx}}, {{cite medrxiv}}, {{cite ssrn}}, before generation of COinS data. if utilities.in_array (config.CitationClass, whitelist.preprint_template_list_t) then -- |arxiv= or |eprint= required for cite arxiv; |biorxiv=, |citeseerx=, |medrxiv=, |ssrn= required for their templates if not (args[cfg.id_handlers[config.CitationClass:upper()].parameters[1]] or -- can't use ID_list_coins k/v table here because invalid parameters omitted args[cfg.id_handlers[config.CitationClass:upper()].parameters[2]]) then -- which causes unexpected parameter missing error message utilities.set_message ('err_' .. config.CitationClass .. '_missing'); -- add error message end Periodical = ({['arxiv'] = 'arXiv', ['biorxiv'] = 'bioRxiv', ['citeseerx'] = 'CiteSeerX', ['medrxiv'] = 'medRxiv', ['ssrn'] = 'Social Science Research Network'})[config.CitationClass]; end -- Link the title of the work if no |url= was provided, but we have a |pmc= or a |doi= with |doi-access=free if config.CitationClass == "journal" and not utilities.is_set (URL) and not utilities.is_set (TitleLink) and not utilities.in_array (cfg.keywords_xlate[Title], {'off', 'none'}) then -- TODO: remove 'none' once existing citations have been switched to 'off', so 'none' can be used as token for "no title" instead if 'none' ~= cfg.keywords_xlate[auto_select] then -- if auto-linking not disabled if identifiers.auto_link_urls[auto_select] then -- manual selection URL = identifiers.auto_link_urls[auto_select]; -- set URL to be the same as identifier's external link URL_origin = cfg.id_handlers[auto_select:upper()].parameters[1]; -- set URL_origin to parameter name for use in error message if citation is missing a |title= elseif identifiers.auto_link_urls['pmc'] then -- auto-select PMC URL = identifiers.auto_link_urls['pmc']; -- set URL to be the same as the PMC external link if not embargoed URL_origin = cfg.id_handlers['PMC'].parameters[1]; -- set URL_origin to parameter name for use in error message if citation is missing a |title= elseif identifiers.auto_link_urls['doi'] then -- auto-select DOI URL = identifiers.auto_link_urls['doi']; URL_origin = cfg.id_handlers['DOI'].parameters[1]; end end if utilities.is_set (URL) then -- set when using an identifier-created URL if utilities.is_set (AccessDate) then -- |access-date= requires |url=; identifier-created URL is not |url= utilities.set_message ('err_accessdate_missing_url'); -- add an error message AccessDate = ''; -- unset end if utilities.is_set (ArchiveURL) then -- |archive-url= requires |url=; identifier-created URL is not |url= utilities.set_message ('err_archive_missing_url'); -- add an error message ArchiveURL = ''; -- unset end end end -- At this point fields may be nil if they weren't specified in the template use. We can use that fact. -- Test if citation has no title if not utilities.is_set (Title) and not utilities.is_set (TransTitle) and not utilities.is_set (ScriptTitle) then -- has special case for cite episode utilities.set_message ('err_citation_missing_title', {'episode' == config.CitationClass and 'series' or 'title'}); end if utilities.in_array (cfg.keywords_xlate[Title], {'off', 'none'}) and utilities.in_array (config.CitationClass, {'journal', 'citation'}) and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) and ('journal' == Periodical_origin or 'script-journal' == ScriptPeriodical_origin) then -- special case for journal cites Title = ''; -- set title to empty string utilities.set_message ('maint_untitled'); -- add maint cat end -- COinS metadata (see <http://ocoins.info/>) for automated parsing of citation information. -- handle the oddity that is cite encyclopedia and {{citation |encyclopedia=something}}. Here we presume that -- when Periodical, Title, and Chapter are all set, then Periodical is the book (encyclopedia) title, Title -- is the article title, and Chapter is a section within the article. So, we remap local coins_chapter = Chapter; -- default assuming that remapping not required local coins_title = Title; -- et tu if 'encyclopaedia' == config.CitationClass or ('citation' == config.CitationClass and utilities.is_set (Encyclopedia)) then if utilities.is_set (Chapter) and utilities.is_set (Title) and utilities.is_set (Periodical) then -- if all are used then coins_chapter = Title; -- remap coins_title = Periodical; end end local coins_author = a; -- default for coins rft.au if 0 < #c then -- but if contributor list coins_author = c; -- use that instead end -- this is the function call to COinS() local OCinSoutput = metadata.COinS({ ['Periodical'] = utilities.strip_apostrophe_markup (Periodical), -- no markup in the metadata ['Encyclopedia'] = Encyclopedia, -- just a flag; content ignored by ~/COinS ['Chapter'] = metadata.make_coins_title (coins_chapter, ScriptChapter), -- Chapter and ScriptChapter stripped of bold / italic / accept-as-written markup ['Degree'] = Degree; -- cite thesis only ['Title'] = metadata.make_coins_title (coins_title, ScriptTitle), -- Title and ScriptTitle stripped of bold / italic / accept-as-written markup ['PublicationPlace'] = PublicationPlace, ['Date'] = COinS_date.rftdate, -- COinS_date.* has correctly formatted date values if Date is valid; ['Season'] = COinS_date.rftssn, ['Quarter'] = COinS_date.rftquarter, ['Chron'] = COinS_date.rftchron, ['Series'] = Series, ['Volume'] = Volume, ['Issue'] = Issue, ['ArticleNumber'] = ArticleNumber, ['Pages'] = coins_pages or metadata.get_coins_pages (first_set ({Sheet, Sheets, Page, Pages, At, QuotePage, QuotePages}, 7)), -- pages stripped of external links ['Edition'] = Edition, ['PublisherName'] = PublisherName or Newsgroup, -- any apostrophe markup already removed from PublisherName ['URL'] = first_set ({ChapterURL, URL}, 2), ['Authors'] = coins_author, ['ID_list'] = ID_list_coins, ['RawPage'] = this_page.prefixedText, }, config.CitationClass); -- Account for the oddities that are {{cite arxiv}}, {{cite biorxiv}}, {{cite citeseerx}}, {{cite medrxiv}}, and {{cite ssrn}} AFTER generation of COinS data. if utilities.in_array (config.CitationClass, whitelist.preprint_template_list_t) then -- we have set rft.jtitle in COinS to arXiv, bioRxiv, CiteSeerX, medRxiv, or ssrn now unset so it isn't displayed Periodical = ''; -- periodical not allowed in these templates; if article has been published, use cite journal end -- special case for cite newsgroup. Do this after COinS because we are modifying Publishername to include some static text if 'newsgroup' == config.CitationClass and utilities.is_set (Newsgroup) then PublisherName = utilities.substitute (cfg.messages['newsgroup'], external_link( 'news:' .. Newsgroup, Newsgroup, Newsgroup_origin, nil )); end local Editors; local EditorCount; -- used only for choosing {ed.) or (eds.) annotation at end of editor name-list local Contributors; -- assembled contributors name list local contributor_etal; local Translators; -- assembled translators name list local translator_etal; local t = {}; -- translators list from |translator-lastn= / translator-firstn= pairs t = extract_names (args, 'TranslatorList'); -- fetch translator list from |translatorn= / |translator-lastn=, -firstn=, -linkn=, -maskn= local Interviewers; local interviewers_list = {}; interviewers_list = extract_names (args, 'InterviewerList'); -- process preferred interviewers parameters local interviewer_etal; -- Now perform various field substitutions. -- We also add leading spaces and surrounding markup and punctuation to the -- various parts of the citation, but only when they are non-nil. do local last_first_list; local control = { format = NameListStyle, -- empty string, '&', 'amp', 'and', or 'vanc' maximum = nil, -- as if display-authors or display-editors not set mode = Mode }; do -- do editor name list first because the now unsupported coauthors used to modify control table local display_names, param = display_names_select (cfg.global_cs1_config_t['DisplayEditors'], A['DisplayEditors'], A:ORIGIN ('DisplayEditors'), #e); control.maximum, editor_etal = get_display_names (display_names, #e, 'editors', editor_etal, param); Editors, EditorCount = list_people (control, e, editor_etal); if 1 == EditorCount and (true == editor_etal or 1 < #e) then -- only one editor displayed but includes etal then EditorCount = 2; -- spoof to display (eds.) annotation end end do -- now do interviewers local display_names, param = display_names_select (cfg.global_cs1_config_t['DisplayInterviewers'], A['DisplayInterviewers'], A:ORIGIN ('DisplayInterviewers'), #interviewers_list); control.maximum, interviewer_etal = get_display_names (display_names, #interviewers_list, 'interviewers', interviewer_etal, param); Interviewers = list_people (control, interviewers_list, interviewer_etal); end do -- now do translators local display_names, param = display_names_select (cfg.global_cs1_config_t['DisplayTranslators'], A['DisplayTranslators'], A:ORIGIN ('DisplayTranslators'), #t); control.maximum, translator_etal = get_display_names (display_names, #t, 'translators', translator_etal, param); Translators = list_people (control, t, translator_etal); end do -- now do contributors local display_names, param = display_names_select (cfg.global_cs1_config_t['DisplayContributors'], A['DisplayContributors'], A:ORIGIN ('DisplayContributors'), #c); control.maximum, contributor_etal = get_display_names (display_names, #c, 'contributors', contributor_etal, param); Contributors = list_people (control, c, contributor_etal); end do -- now do authors local display_names, param = display_names_select (cfg.global_cs1_config_t['DisplayAuthors'], A['DisplayAuthors'], A:ORIGIN ('DisplayAuthors'), #a, author_etal); control.maximum, author_etal = get_display_names (display_names, #a, 'authors', author_etal, param); last_first_list = list_people (control, a, author_etal); if utilities.is_set (Authors) then Authors, author_etal = name_has_etal (Authors, author_etal, false, 'authors'); -- find and remove variations on et al. if author_etal then Authors = Authors .. ' ' .. cfg.messages['et al']; -- add et al. to authors parameter end else Authors = last_first_list; -- either an author name list or an empty string end end -- end of do if utilities.is_set (Authors) and utilities.is_set (Collaboration) then Authors = Authors .. ' (' .. Collaboration .. ')'; -- add collaboration after et al. end end local ConferenceFormat = A['ConferenceFormat']; local ConferenceURL = A['ConferenceURL']; ConferenceFormat = style_format (ConferenceFormat, ConferenceURL, 'conference-format', 'conference-url'); Format = style_format (Format, URL, 'format', 'url'); -- special case for chapter format so no error message or cat when chapter not supported if not (utilities.in_array (config.CitationClass, {'web', 'news', 'journal', 'magazine', 'pressrelease', 'podcast', 'newsgroup', 'arxiv', 'biorxiv', 'citeseerx', 'medrxiv', 'ssrn'}) or ('citation' == config.CitationClass and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) and not utilities.is_set (Encyclopedia))) then ChapterFormat = style_format (ChapterFormat, ChapterURL, 'chapter-format', 'chapter-url'); end if not utilities.is_set (URL) then if utilities.in_array (config.CitationClass, {"web", "podcast", "mailinglist"}) or -- |url= required for cite web, cite podcast, and cite mailinglist ('citation' == config.CitationClass and ('website' == Periodical_origin or 'script-website' == ScriptPeriodical_origin)) then -- and required for {{citation}} with |website= or |script-website= utilities.set_message ('err_cite_web_url'); end -- do we have |accessdate= without either |url= or |chapter-url=? if utilities.is_set (AccessDate) and not utilities.is_set (ChapterURL) then -- ChapterURL may be set when URL is not set; utilities.set_message ('err_accessdate_missing_url'); AccessDate = ''; end end local UrlStatus = is_valid_parameter_value (A['UrlStatus'], A:ORIGIN('UrlStatus'), cfg.keywords_lists['url-status'], ''); local OriginalURL local OriginalURL_origin local OriginalFormat local OriginalAccess; UrlStatus = UrlStatus:lower(); -- used later when assembling archived text if utilities.is_set ( ArchiveURL ) then if utilities.is_set (ChapterURL) then -- if chapter-url= is set apply archive url to it OriginalURL = ChapterURL; -- save copy of source chapter's url for archive text OriginalURL_origin = ChapterURL_origin; -- name of |chapter-url= parameter for error messages OriginalFormat = ChapterFormat; -- and original |chapter-format= if utilities.in_array (UrlStatus, {'unfit', 'deviated', 'dead', 'usurped', 'bot: unknown'}) then ChapterURL = ArchiveURL -- swap-in the archive's URL ChapterURL_origin = A:ORIGIN('ArchiveURL') -- name of |archive-url= parameter for error messages ChapterFormat = ArchiveFormat or ''; -- swap in archive's format ChapterUrlAccess = nil; -- restricted access levels do not make sense for archived URLs end elseif utilities.is_set (URL) then OriginalURL = URL; -- save copy of original source URL OriginalURL_origin = URL_origin; -- name of URL parameter for error messages OriginalFormat = Format; -- and original |format= OriginalAccess = UrlAccess; if utilities.in_array (UrlStatus, {'unfit', 'deviated', 'dead', 'usurped', 'bot: unknown'}) then -- if URL set then |archive-url= applies to it URL = ArchiveURL -- swap-in the archive's URL URL_origin = A:ORIGIN('ArchiveURL') -- name of archive URL parameter for error messages Format = ArchiveFormat or ''; -- swap in archive's format UrlAccess = nil; -- restricted access levels do not make sense for archived URLs end end elseif utilities.is_set (UrlStatus) then -- if |url-status= is set when |archive-url= is not set utilities.set_message ('maint_url_status'); -- add maint cat end if utilities.in_array (config.CitationClass, {'web', 'news', 'journal', 'magazine', 'pressrelease', 'podcast', 'newsgroup', 'arxiv', 'biorxiv', 'citeseerx', 'medrxiv', 'ssrn'}) or -- if any of the 'periodical' cites except encyclopedia ('citation' == config.CitationClass and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) and not utilities.is_set (Encyclopedia)) then local chap_param; if utilities.is_set (Chapter) then -- get a parameter name from one of these chapter related meta-parameters chap_param = A:ORIGIN ('Chapter') elseif utilities.is_set (TransChapter) then chap_param = A:ORIGIN ('TransChapter') elseif utilities.is_set (ChapterURL) then chap_param = A:ORIGIN ('ChapterURL') elseif utilities.is_set (ScriptChapter) then chap_param = ScriptChapter_origin; else utilities.is_set (ChapterFormat) chap_param = A:ORIGIN ('ChapterFormat') end if utilities.is_set (chap_param) then -- if we found one utilities.set_message ('err_chapter_ignored', {chap_param}); -- add error message Chapter = ''; -- and set them to empty string to be safe with concatenation TransChapter = ''; ChapterURL = ''; ScriptChapter = ''; ChapterFormat = ''; end else -- otherwise, format chapter / article title local no_quotes = false; -- default assume that we will be quoting the chapter parameter value if utilities.is_set (Contribution) and 0 < #c then -- if this is a contribution with contributor(s) if utilities.in_array (Contribution:lower(), cfg.keywords_lists.contribution) then -- and a generic contribution title no_quotes = true; -- then render it unquoted end end Chapter = format_chapter_title (ScriptChapter, ScriptChapter_origin, Chapter, Chapter_origin, TransChapter, TransChapter_origin, ChapterURL, ChapterURL_origin, no_quotes, ChapterUrlAccess); -- Contribution is also in Chapter if utilities.is_set (Chapter) then Chapter = Chapter .. ChapterFormat ; if 'map' == config.CitationClass and utilities.is_set (TitleType) then Chapter = Chapter .. ' ' .. TitleType; -- map annotation here; not after title end Chapter = Chapter .. sepc .. ' '; elseif utilities.is_set (ChapterFormat) then -- |chapter= not set but |chapter-format= is so ... Chapter = ChapterFormat .. sepc .. ' '; -- ... ChapterFormat has error message, we want to see it end end -- Format main title local plain_title = false; local accept_title; Title, accept_title = utilities.has_accept_as_written (Title, true); -- remove accept-this-as-written markup when it wraps all of <Title> if accept_title and ('' == Title) then -- only support forced empty for now "(())" Title = cfg.messages['notitle']; -- replace by predefined "No title" message -- TODO: utilities.set_message ( 'err_redundant_parameters', ...); -- issue proper error message instead of muting ScriptTitle = ''; -- just mute for now TransTitle = ''; -- just mute for now plain_title = true; -- suppress text decoration for descriptive title utilities.set_message ('maint_untitled'); -- add maint cat end if not accept_title then -- <Title> not wrapped in accept-as-written markup if '...' == Title:sub (-3) then -- if ellipsis is the last three characters of |title= Title = Title:gsub ('(%.%.%.)%.+$', '%1'); -- limit the number of dots to three elseif not mw.ustring.find (Title, '%.%s*%a%.$') and -- end of title is not a 'dot-(optional space-)letter-dot' initialism ... not mw.ustring.find (Title, '%s+%a%.$') then -- ...and not a 'space-letter-dot' initial (''Allium canadense'' L.) Title = mw.ustring.gsub(Title, '%' .. sepc .. '$', ''); -- remove any trailing separator character; sepc and ms.ustring() here for languages that use multibyte separator characters end if utilities.is_set (ArchiveURL) and is_archived_copy (Title) then utilities.set_message ('maint_archived_copy'); -- add maintenance category before we modify the content of Title end if is_generic ('generic_titles', Title) then utilities.set_message ('err_generic_title'); -- set an error message end end if (not plain_title) and (utilities.in_array (config.CitationClass, {'web', 'news', 'journal', 'magazine', 'document', 'pressrelease', 'podcast', 'newsgroup', 'mailinglist', 'interview', 'arxiv', 'biorxiv', 'citeseerx', 'medrxiv', 'ssrn'}) or ('citation' == config.CitationClass and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) and not utilities.is_set (Encyclopedia)) or ('map' == config.CitationClass and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)))) then -- special case for cite map when the map is in a periodical treat as an article Title = kern_quotes (Title); -- if necessary, separate title's leading and trailing quote marks from module provided quote marks Title = utilities.wrap_style ('quoted-title', Title); Title = script_concatenate (Title, ScriptTitle, 'script-title'); -- <bdi> tags, lang attribute, categorization, etc.; must be done after title is wrapped TransTitle = utilities.wrap_style ('trans-quoted-title', TransTitle ); elseif plain_title or ('report' == config.CitationClass) then -- no styling for cite report and descriptive titles (otherwise same as above) Title = script_concatenate (Title, ScriptTitle, 'script-title'); -- <bdi> tags, lang attribute, categorization, etc.; must be done after title is wrapped TransTitle = utilities.wrap_style ('trans-quoted-title', TransTitle ); -- for cite report, use this form for trans-title else Title = utilities.wrap_style ('italic-title', Title); Title = script_concatenate (Title, ScriptTitle, 'script-title'); -- <bdi> tags, lang attribute, categorization, etc.; must be done after title is wrapped TransTitle = utilities.wrap_style ('trans-italic-title', TransTitle); end if utilities.is_set (TransTitle) then if utilities.is_set (Title) then TransTitle = " " .. TransTitle; else utilities.set_message ('err_trans_missing_title', {'title'}); end end if utilities.is_set (Title) then -- TODO: is this the right place to be making Wikisource URLs? if utilities.is_set (TitleLink) and utilities.is_set (URL) then utilities.set_message ('err_wikilink_in_url'); -- set an error message because we can't have both TitleLink = ''; -- unset end if not utilities.is_set (TitleLink) and utilities.is_set (URL) then Title = external_link (URL, Title, URL_origin, UrlAccess) .. TransTitle .. Format; URL = ''; -- unset these because no longer needed Format = ""; elseif utilities.is_set (TitleLink) and not utilities.is_set (URL) then local ws_url; ws_url = wikisource_url_make (TitleLink); -- ignore ws_label return; not used here if ws_url then Title = external_link (ws_url, Title .. '&nbsp;', 'ws link in title-link'); -- space char after Title to move icon away from italic text; TODO: a better way to do this? Title = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], TitleLink, Title}); Title = Title .. TransTitle; else Title = utilities.make_wikilink (TitleLink, Title) .. TransTitle; end else local ws_url, ws_label, L; -- Title has italic or quote markup by the time we get here which causes is_wikilink() to return 0 (not a wikilink) ws_url, ws_label, L = wikisource_url_make (Title:gsub('^[\'"]*(.-)[\'"]*$', '%1')); -- make ws URL from |title= interwiki link (strip italic or quote markup); link portion L becomes tooltip label if ws_url then Title = Title:gsub ('%b[]', ws_label); -- replace interwiki link with ws_label to retain markup Title = external_link (ws_url, Title .. '&nbsp;', 'ws link in title'); -- space char after Title to move icon away from italic text; TODO: a better way to do this? Title = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], L, Title}); Title = Title .. TransTitle; else Title = Title .. TransTitle; end end else Title = TransTitle; end if utilities.is_set (Place) then Place = " " .. wrap_msg ('written', Place, use_lowercase) .. sepc .. " "; end local ConferenceURL_origin = A:ORIGIN('ConferenceURL'); -- get name of parameter that holds ConferenceURL if utilities.is_set (Conference) then if utilities.is_set (ConferenceURL) then Conference = external_link( ConferenceURL, Conference, ConferenceURL_origin, nil ); end Conference = sepc .. " " .. Conference .. ConferenceFormat; elseif utilities.is_set (ConferenceURL) then Conference = sepc .. " " .. external_link( ConferenceURL, nil, ConferenceURL_origin, nil ); end local Position = ''; if not utilities.is_set (Position) then local Minutes = A['Minutes']; local Time = A['Time']; if utilities.is_set (Minutes) then if utilities.is_set (Time) then --TODO: make a function for this and similar? utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', 'minutes') .. cfg.presentation['sep_list_pair'] .. utilities.wrap_style ('parameter', 'time')}); end Position = " " .. Minutes .. " " .. cfg.messages['minutes']; else if utilities.is_set (Time) then local TimeCaption = A['TimeCaption'] if not utilities.is_set (TimeCaption) then TimeCaption = cfg.messages['event']; if sepc ~= '.' then TimeCaption = TimeCaption:lower(); end end Position = " " .. TimeCaption .. " " .. Time; end end else Position = " " .. Position; At = ''; end Page, Pages, Sheet, Sheets = format_pages_sheets (Page, Pages, Sheet, Sheets, config.CitationClass, Periodical_origin, sepc, NoPP, use_lowercase); At = utilities.is_set (At) and (sepc .. " " .. At) or ""; Position = utilities.is_set (Position) and (sepc .. " " .. Position) or ""; if config.CitationClass == 'map' then local Sections = A['Sections']; -- Section (singular) is an alias of Chapter so set earlier local Inset = A['Inset']; if utilities.is_set ( Inset ) then Inset = sepc .. " " .. wrap_msg ('inset', Inset, use_lowercase); end if utilities.is_set ( Sections ) then Section = sepc .. " " .. wrap_msg ('sections', Sections, use_lowercase); elseif utilities.is_set ( Section ) then Section = sepc .. " " .. wrap_msg ('section', Section, use_lowercase); end At = At .. Inset .. Section; end local Others = A['Others']; if utilities.is_set (Others) and 0 == #a and 0 == #e then -- add maint cat when |others= has value and used without |author=, |editor= if config.CitationClass == "AV-media-notes" or config.CitationClass == "audio-visual" then -- special maint for AV/M which has a lot of 'false' positives right now utilities.set_message ('maint_others_avm') else utilities.set_message ('maint_others'); end end Others = utilities.is_set (Others) and (sepc .. " " .. Others) or ""; if utilities.is_set (Translators) then Others = safe_join ({sepc .. ' ', wrap_msg ('translated', Translators, use_lowercase), Others}, sepc); end if utilities.is_set (Interviewers) then Others = safe_join ({sepc .. ' ', wrap_msg ('interview', Interviewers, use_lowercase), Others}, sepc); end local TitleNote = A['TitleNote']; TitleNote = utilities.is_set (TitleNote) and (sepc .. " " .. TitleNote) or ""; if utilities.is_set (Edition) then if Edition:match ('%f[%a][Ee]d%n?%.?$') or Edition:match ('%f[%a][Ee]dition$') then -- Ed, ed, Ed., ed., Edn, edn, Edn., edn. utilities.set_message ('err_extra_text_edition'); -- add error message end Edition = " " .. wrap_msg ('edition', Edition); else Edition = ''; end Series = utilities.is_set (Series) and wrap_msg ('series', {sepc, Series}) or ""; -- not the same as SeriesNum local Agency = A['Agency'] or ''; -- |agency= only supported in {{cite news}}, {{cite press release}}, {{cite web}} and certain {{citation}} templates if utilities.is_set (Agency) then -- this testing done here because {{citation}} supports 'news' citations if utilities.in_array (config.CitationClass, {'news', 'pressrelease', 'web'}) or ('citation' == config.CitationClass and utilities.in_array (Periodical_origin, {"newspaper", "work"})) then Agency = wrap_msg ('agency', {sepc, Agency}); -- format for rendering else Agency = ''; -- unset; not supported utilities.set_message ('err_parameter_ignored', {'agency'}); -- add error message end end Volume = format_volume_issue (Volume, Issue, ArticleNumber, config.CitationClass, Periodical_origin, sepc, use_lowercase); if utilities.is_set (AccessDate) then local retrv_text = " " .. cfg.messages['retrieved'] local status, result = pcall(formatDate, AccessDate) -- РУВИКИ: человекочитаемые даты if status then AccessDate = string.format("<span class='date'>%s</span>", result) else AccessDate = string.format("<span class='error'>(Строка «%s» не является верной датой, пожалуйста, укажите дату в формате <code>ГГГГ-ММ-ДД</code>)</span>", AccessDate) end -- AccessDate = nowrap_date (AccessDate); -- wrap in nowrap span if date in appropriate format if (sepc ~= ".") then retrv_text = retrv_text:lower() end -- if mode is cs2, lower case AccessDate = utilities.substitute (retrv_text, AccessDate); -- add retrieved text AccessDate = utilities.substitute (cfg.presentation['accessdate'], {sepc, AccessDate}); -- allow editors to hide accessdates end if utilities.is_set (ID) then ID = sepc .. " " .. ID; end local Docket = A['Docket']; if "thesis" == config.CitationClass and utilities.is_set (Docket) then ID = sepc .. " Docket " .. Docket .. ID; end if "report" == config.CitationClass and utilities.is_set (Docket) then -- for cite report when |docket= is set ID = sepc .. ' ' .. Docket; -- overwrite ID even if |id= is set end if utilities.is_set (URL) then URL = " " .. external_link( URL, nil, URL_origin, UrlAccess ); end local Quote = A['Quote']; local TransQuote = A['TransQuote']; local ScriptQuote = A['ScriptQuote']; if utilities.is_set (Quote) or utilities.is_set (TransQuote) or utilities.is_set (ScriptQuote) then if utilities.is_set (Quote) then if Quote:sub(1, 1) == '"' and Quote:sub(-1, -1) == '"' then -- if first and last characters of quote are quote marks Quote = Quote:sub(2, -2); -- strip them off end end Quote = kern_quotes (Quote); -- kern if needed Quote = utilities.wrap_style ('quoted-text', Quote ); -- wrap in <q>...</q> tags if utilities.is_set (ScriptQuote) then Quote = script_concatenate (Quote, ScriptQuote, 'script-quote'); -- <bdi> tags, lang attribute, categorization, etc.; must be done after quote is wrapped end if utilities.is_set (TransQuote) then if TransQuote:sub(1, 1) == '"' and TransQuote:sub(-1, -1) == '"' then -- if first and last characters of |trans-quote are quote marks TransQuote = TransQuote:sub(2, -2); -- strip them off end Quote = Quote .. " " .. utilities.wrap_style ('trans-quoted-title', TransQuote ); end if utilities.is_set (QuotePage) or utilities.is_set (QuotePages) then -- add page prefix local quote_prefix = ''; if utilities.is_set (QuotePage) then extra_text_in_page_check (QuotePage, 'quote-page'); -- add to maint cat if |quote-page= value begins with what looks like p., pp., etc. if not NoPP then quote_prefix = utilities.substitute (cfg.messages['p-prefix'], {sepc, QuotePage}), '', '', ''; else quote_prefix = utilities.substitute (cfg.messages['nopp'], {sepc, QuotePage}), '', '', ''; end elseif utilities.is_set (QuotePages) then extra_text_in_page_check (QuotePages, 'quote-pages'); -- add to maint cat if |quote-pages= value begins with what looks like p., pp., etc. if tonumber(QuotePages) ~= nil and not NoPP then -- if only digits, assume single page quote_prefix = utilities.substitute (cfg.messages['p-prefix'], {sepc, QuotePages}), '', ''; elseif not NoPP then quote_prefix = utilities.substitute (cfg.messages['pp-prefix'], {sepc, QuotePages}), '', ''; else quote_prefix = utilities.substitute (cfg.messages['nopp'], {sepc, QuotePages}), '', ''; end end Quote = quote_prefix .. ": " .. Quote; else Quote = sepc .. " " .. Quote; end PostScript = ""; -- cs1|2 does not supply terminal punctuation when |quote= is set end -- We check length of PostScript here because it will have been nuked by -- the quote parameters. We'd otherwise emit a message even if there wasn't -- a displayed postscript. -- TODO: Should the max size (1) be configurable? -- TODO: Should we check a specific pattern? if utilities.is_set(PostScript) and mw.ustring.len(PostScript) > 1 then utilities.set_message ('maint_postscript') end local Archived; if utilities.is_set (ArchiveURL) then if not utilities.is_set (ArchiveDate) then -- ArchiveURL set but ArchiveDate not set utilities.set_message ('err_archive_missing_date'); -- emit an error message ArchiveURL = ''; -- empty string for concatenation ArchiveDate = ''; -- empty string for concatenation end else if utilities.is_set (ArchiveDate) then -- ArchiveURL not set but ArchiveDate is set utilities.set_message ('err_archive_date_missing_url'); -- emit an error message ArchiveURL = ''; -- empty string for concatenation ArchiveDate = ''; -- empty string for concatenation end end if utilities.is_set (ArchiveURL) then local arch_text; local status, result = pcall(formatDate, ArchiveDate) -- РУВИКИ: человекочитаемые даты if status then ArchiveDate = string.format("<span class='date'>%s</span>", result) else ArchiveDate = string.format("<span class='error'>(Строка «%s» не является верной датой, пожалуйста, укажите дату в формате <code>ГГГГ-ММ-ДД</code>)</span>", ArchiveDate) end if "live" == UrlStatus or "" == UrlStatus then arch_text = cfg.messages['archived']; if sepc ~= "." then arch_text = arch_text:lower() end if utilities.is_set (ArchiveDate) then Archived = sepc .. ' ' .. utilities.substitute ( cfg.messages['archived-live'], {external_link( ArchiveURL, arch_text, A:ORIGIN('ArchiveURL'), nil) .. ArchiveFormat, ArchiveDate } ); else Archived = ''; end if not utilities.is_set (OriginalURL) then utilities.set_message ('err_archive_missing_url'); Archived = ''; -- empty string for concatenation end elseif utilities.is_set (OriginalURL) then -- UrlStatus is empty, 'dead', 'unfit', 'usurped', 'bot: unknown' if utilities.in_array (UrlStatus, {'unfit', 'usurped', 'bot: unknown'}) then arch_text = cfg.messages['archived-unfit']; if sepc ~= "." then arch_text = arch_text:lower() end Archived = sepc .. ' ' .. arch_text .. ArchiveDate; -- format already styled if 'bot: unknown' == UrlStatus then utilities.set_message ('maint_bot_unknown'); -- and add a category if not already added else utilities.set_message ('maint_unfit'); -- and add a category if not already added end else -- UrlStatus is empty, 'dead' arch_text = cfg.messages['archived-dead']; if sepc ~= "." then arch_text = arch_text:lower() end if utilities.is_set (ArchiveDate) then Archived = sepc .. " " .. utilities.substitute ( arch_text, { external_link( OriginalURL, cfg.messages['original'], OriginalURL_origin, OriginalAccess ) .. OriginalFormat, ArchiveDate } ); -- format already styled else Archived = ''; -- unset for concatenation end end else -- OriginalUrl not set utilities.set_message ('err_archive_missing_url'); Archived = ''; -- empty string for concatenation end elseif utilities.is_set (ArchiveFormat) then Archived = ArchiveFormat; -- if set and ArchiveURL not set ArchiveFormat has error message else Archived = ''; end local TranscriptURL = A['TranscriptURL'] local TranscriptFormat = A['TranscriptFormat']; TranscriptFormat = style_format (TranscriptFormat, TranscriptURL, 'transcript-format', 'transcripturl'); local Transcript = A['Transcript']; local TranscriptURL_origin = A:ORIGIN('TranscriptURL'); -- get name of parameter that holds TranscriptURL if utilities.is_set (Transcript) then if utilities.is_set (TranscriptURL) then Transcript = external_link( TranscriptURL, Transcript, TranscriptURL_origin, nil ); end Transcript = sepc .. ' ' .. Transcript .. TranscriptFormat; elseif utilities.is_set (TranscriptURL) then Transcript = external_link( TranscriptURL, nil, TranscriptURL_origin, nil ); end local Publisher; if utilities.is_set (PublicationDate) then PublicationDate = wrap_msg ('published', PublicationDate); end if utilities.is_set (PublisherName) then if utilities.is_set (PublicationPlace) then Publisher = sepc .. " " .. PublicationPlace .. ": " .. PublisherName .. PublicationDate; else Publisher = sepc .. " " .. PublisherName .. PublicationDate; end elseif utilities.is_set (PublicationPlace) then Publisher= sepc .. " " .. PublicationPlace .. PublicationDate; else Publisher = PublicationDate; end -- Several of the above rely upon detecting this as nil, so do it last. if (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical) or utilities.is_set (TransPeriodical)) then if utilities.is_set (Title) or utilities.is_set (TitleNote) then Periodical = sepc .. " " .. format_periodical (ScriptPeriodical, ScriptPeriodical_origin, Periodical, TransPeriodical, TransPeriodical_origin); else Periodical = format_periodical (ScriptPeriodical, ScriptPeriodical_origin, Periodical, TransPeriodical, TransPeriodical_origin); end end local Language = A['Language']; if utilities.is_set (Language) then Language = language_parameter (Language); -- format, categories, name from ISO639-1, etc. else Language=''; -- language not specified so make sure this is an empty string; --[[ TODO: need to extract the wrap_msg from language_parameter so that we can solve parentheses bunching problem with Format/Language/TitleType ]] end --[[ Handle the oddity that is cite speech. This code overrides whatever may be the value assigned to TitleNote (through |department=) and forces it to be " (Speech)" so that the annotation directly follows the |title= parameter value in the citation rather than the |event= parameter value (if provided). ]] if "speech" == config.CitationClass then -- cite speech only TitleNote = TitleType; -- move TitleType to TitleNote so that it renders ahead of |event= TitleType = ''; -- and unset if utilities.is_set (Periodical) then -- if Periodical, perhaps because of an included |website= or |journal= parameter if utilities.is_set (Conference) then -- and if |event= is set Conference = Conference .. sepc .. " "; -- then add appropriate punctuation to the end of the Conference variable before rendering end end end -- Piece all bits together at last. Here, all should be non-nil. -- We build things this way because it is more efficient in LUA -- not to keep reassigning to the same string variable over and over. local tcommon; local tcommon2; -- used for book cite when |contributor= is set if utilities.in_array (config.CitationClass, {"book", "citation"}) and not utilities.is_set (Periodical) then -- special cases for book cites if utilities.is_set (Contributors) then -- when we are citing foreword, preface, introduction, etc. tcommon = safe_join ({Title, TitleNote}, sepc); -- author and other stuff will come after this and before tcommon2 tcommon2 = safe_join ({TitleType, Series, Language, Volume, Others, Edition, Publisher}, sepc); else tcommon = safe_join ({Title, TitleNote, TitleType, Series, Language, Volume, Others, Edition, Publisher}, sepc); end elseif 'map' == config.CitationClass then -- special cases for cite map if utilities.is_set (Chapter) then -- map in a book; TitleType is part of Chapter tcommon = safe_join ({Title, Edition, Scale, Series, Language, Cartography, Others, Publisher, Volume}, sepc); elseif utilities.is_set (Periodical) then -- map in a periodical tcommon = safe_join ({Title, TitleType, Periodical, Scale, Series, Language, Cartography, Others, Publisher, Volume}, sepc); else -- a sheet or stand-alone map tcommon = safe_join ({Title, TitleType, Edition, Scale, Series, Language, Cartography, Others, Publisher}, sepc); end elseif 'episode' == config.CitationClass then -- special case for cite episode tcommon = safe_join ({Title, TitleNote, TitleType, Series, Language, Edition, Publisher}, sepc); else -- all other CS1 templates tcommon = safe_join ({Title, TitleNote, Conference, Periodical, TitleType, Series, Language, Volume, Others, Edition, Publisher, Agency}, sepc); end if #ID_list > 0 then ID_list = safe_join( { sepc .. " ", table.concat( ID_list, sepc .. " " ), ID }, sepc ); else ID_list = ID; end local Via = A['Via']; Via = utilities.is_set (Via) and wrap_msg ('via', Via) or ''; local idcommon; if 'audio-visual' == config.CitationClass or 'episode' == config.CitationClass then -- special case for cite AV media & cite episode position transcript idcommon = safe_join( { ID_list, URL, Archived, Transcript, AccessDate, Via, Quote }, sepc ); else idcommon = safe_join( { ID_list, URL, Archived, AccessDate, Via, Quote }, sepc ); end local text; local pgtext = Position .. Sheet .. Sheets .. Page .. Pages .. At; local OrigDate = A['OrigDate']; OrigDate = utilities.is_set (OrigDate) and wrap_msg ('origdate', OrigDate) or ''; if utilities.is_set (Date) then if utilities.is_set (Authors) or utilities.is_set (Editors) then -- date follows authors or editors when authors not set Date = " (" .. Date .. ")" .. OrigDate .. sepc .. " "; -- in parentheses else -- neither of authors and editors set if (string.sub(tcommon, -1, -1) == sepc) then -- if the last character of tcommon is sepc Date = " " .. Date .. OrigDate; -- Date does not begin with sepc else Date = sepc .. " " .. Date .. OrigDate; -- Date begins with sepc end end end if utilities.is_set (Authors) then if (not utilities.is_set (Date)) then -- when date is set it's in parentheses; no Authors termination Authors = terminate_name_list (Authors, sepc); -- when no date, terminate with 0 or 1 sepc and a space end if utilities.is_set (Editors) then local in_text = ''; local post_text = ''; if utilities.is_set (Chapter) and 0 == #c then in_text = cfg.messages['in'] .. ' '; if (sepc ~= '.') then in_text = in_text:lower(); -- lowercase for cs2 end end if EditorCount <= 1 then post_text = ' (' .. cfg.messages['editor'] .. ')'; -- be consistent with no-author, no-date case else post_text = ' (' .. cfg.messages['editors'] .. ')'; end Editors = terminate_name_list (in_text .. Editors .. post_text, sepc); -- terminate with 0 or 1 sepc and a space end if utilities.is_set (Contributors) then -- book cite and we're citing the intro, preface, etc. local by_text = sepc .. ' ' .. cfg.messages['by'] .. ' '; if (sepc ~= '.') then by_text = by_text:lower() end -- lowercase for cs2 Authors = by_text .. Authors; -- author follows title so tweak it here if utilities.is_set (Editors) and utilities.is_set (Date) then -- when Editors make sure that Authors gets terminated Authors = terminate_name_list (Authors, sepc); -- terminate with 0 or 1 sepc and a space end if (not utilities.is_set (Date)) then -- when date is set it's in parentheses; no Contributors termination Contributors = terminate_name_list (Contributors, sepc); -- terminate with 0 or 1 sepc and a space end text = safe_join( {Contributors, Date, Chapter, tcommon, Authors, Place, Editors, tcommon2, pgtext, idcommon }, sepc ); else text = safe_join( {Authors, Date, Chapter, Place, Editors, tcommon, pgtext, idcommon }, sepc ); end elseif utilities.is_set (Editors) then if utilities.is_set (Date) then if EditorCount <= 1 then Editors = Editors .. cfg.presentation['sep_name'] .. cfg.messages['editor']; else Editors = Editors .. cfg.presentation['sep_name'] .. cfg.messages['editors']; end else if EditorCount <= 1 then Editors = Editors .. " (" .. cfg.messages['editor'] .. ")" .. sepc .. " " else Editors = Editors .. " (" .. cfg.messages['editors'] .. ")" .. sepc .. " " end end text = safe_join( {Editors, Date, Chapter, Place, tcommon, pgtext, idcommon}, sepc ); else if utilities.in_array (config.CitationClass, {"journal", "citation"}) and utilities.is_set (Periodical) then text = safe_join( {Chapter, Place, tcommon, pgtext, Date, idcommon}, sepc ); else text = safe_join( {Chapter, Place, tcommon, Date, pgtext, idcommon}, sepc ); end end if utilities.is_set (PostScript) and PostScript ~= sepc then text = safe_join( {text, sepc}, sepc ); -- Deals with italics, spaces, etc. if '.' == sepc then -- remove final seperator if present text = text:gsub ('%' .. sepc .. '$', ''); -- dot must be escaped here else text = mw.ustring.gsub (text, sepc .. '$', ''); -- using ustring for non-dot sepc (likely a non-Latin character) end end text = safe_join( {text, PostScript}, sepc ); -- Now enclose the whole thing in a <cite> element local options_t = {}; options_t.class = cite_class_attribute_make (config.CitationClass, Mode); local Ref = is_valid_parameter_value (A['Ref'], A:ORIGIN('Ref'), cfg.keywords_lists['ref'], nil, true); -- nil when |ref=harv; A['Ref'] else -- Если указан параметр ref, то формируем ref-якорь по логике из рувики -- Если параметр не указан или ref=harv, то формируем якорь по енвики -- После зачистки всех ref=harv (~350), можно будет убрать код внутри utilities.is_set(Ref) if 'none' ~= cfg.keywords_xlate[(Ref and Ref:lower()) or ''] then local citeref_id = Ref local year = first_set ({Year, anchor_year}, 2); -- Year first for legacy citations and for YMD dates that require disambiguation if not utilities.is_set(Ref) then local namelist_t = {}; -- holds selected contributor, author, editor name list if #c > 0 then -- if there is a contributor list namelist_t = c; -- select it elseif #a > 0 then -- or an author list namelist_t = a; elseif #e > 0 then -- or an editor list namelist_t = e; end if #namelist_t > 0 then -- if there are names in namelist_t citeref_id = make_citeref_id (namelist_t, year); -- go make the CITEREF anchor if mw.uri.anchorEncode (citeref_id) == ((Ref and mw.uri.anchorEncode (Ref)) or '') then -- Ref may already be encoded (by {{sfnref}}) so citeref_id must be encoded before comparison utilities.set_message ('maint_ref_duplicates_default'); end else citeref_id = ''; -- unset end elseif mw.ustring.sub(Ref, 0, 7) ~= 'CITEREF' then -- для рувики: иная генерация ref-якорей if mw.ustring.match(citeref_id, '%d%d%d%d') then citeref_id = 'CITEREF' .. citeref_id else local yearForRef = nil if year and mw.ustring.match(year, '^%d%d%d%d$') then yearForRef = mw.ustring.match(year, '^%d%d%d%d$') elseif Date and mw.ustring.match(Date, '%d%d%d%d') then yearForRef = mw.ustring.match(Date, '%d%d%d%d') end if yearForRef then citeref_id = 'CITEREF' .. citeref_id .. yearForRef else citeref_id = '' -- TODO: для рувики: выдавать ошибку? end end end options_t.id = citeref_id or ''; end if string.len (text:gsub('%b<>', '')) <= 2 then -- remove html and html-like tags; then get length of what remains; z.error_cats_t = {}; -- blank the categories list z.error_msgs_t = {}; -- blank the error messages list OCinSoutput = nil; -- blank the metadata string text = ''; -- blank the the citation utilities.set_message ('err_empty_citation'); -- set empty citation message and category end local render_t = {}; -- here we collect the final bits for concatenation into the rendered citation if utilities.is_set (options_t.id) then -- here we wrap the rendered citation in <cite ...>...</cite> tags table.insert (render_t, utilities.substitute (cfg.presentation['cite-id'], {mw.uri.anchorEncode(options_t.id), mw.text.nowiki(options_t.class), text})); -- when |ref= is set or when there is a namelist else table.insert (render_t, utilities.substitute (cfg.presentation['cite'], {mw.text.nowiki(options_t.class), text})); -- when |ref=none or when namelist_t empty and |ref= is missing or is empty end if OCinSoutput then -- blanked when citation is 'empty' so don't bother to add boilerplate metadata span table.insert (render_t, utilities.substitute (cfg.presentation['ocins'], OCinSoutput)); -- format and append metadata to the citation end local template_name = ('citation' == config.CitationClass) and 'citation' or 'cite ' .. (cfg.citation_class_map_t[config.CitationClass] or config.CitationClass); local template_link = '[[Template:' .. template_name .. '|' .. template_name .. ']]'; local msg_prefix = '<code class="cs1-code">{{' .. template_link .. '}}</code>: '; if 0 ~= #z.error_msgs_t then mw.addWarning (utilities.substitute (cfg.messages.warning_msg_e, template_link)); table.insert (render_t, ' '); -- insert a space between citation and its error messages table.sort (z.error_msgs_t); -- sort the error messages list; sorting includes wrapping <span> and <code> tags; hidden-error sorts ahead of visible-error local hidden = true; -- presume that the only error messages emited by this template are hidden for _, v in ipairs (z.error_msgs_t) do -- spin through the list of error messages if v:find ('cs1-visible-error', 1, true) then -- look for the visible error class name hidden = false; -- found one; so don't hide the error message prefix break; -- and done because no need to look further end end z.error_msgs_t[1] = table.concat ({utilities.error_comment (msg_prefix, hidden), z.error_msgs_t[1]}); -- add error message prefix to first error message to prevent extraneous punctuation table.insert (render_t, table.concat (z.error_msgs_t, '; ')); -- make a big string of error messages and add it to the rendering end if 0 ~= #z.maint_cats_t then mw.addWarning (utilities.substitute (cfg.messages.warning_msg_m, template_link)); table.sort (z.maint_cats_t); -- sort the maintenance messages list local maint_msgs_t = {}; -- here we collect all of the maint messages if 0 == #z.error_msgs_t then -- if no error messages table.insert (maint_msgs_t, msg_prefix); -- insert message prefix in maint message livery end for _, v in ipairs( z.maint_cats_t ) do -- append maintenance categories table.insert (maint_msgs_t, -- assemble new maint message and add it to the maint_msgs_t table table.concat ({v, ' (', utilities.substitute (cfg.messages[':cat wikilink'], v), ')'}) ); end table.insert (render_t, utilities.substitute (cfg.presentation['hidden-maint'], table.concat (maint_msgs_t, ' '))); -- wrap the group of maint messages with proper presentation and save end if not no_tracking_cats then local sort_key; local cat_wikilink = 'cat wikilink'; if cfg.enable_sort_keys then -- when namespace sort keys enabled local namespace_number = mw.title.getCurrentTitle().namespace; -- get namespace number for this wikitext sort_key = (0 ~= namespace_number and (cfg.name_space_sort_keys[namespace_number] or cfg.name_space_sort_keys.other)) or nil; -- get sort key character; nil for mainspace cat_wikilink = (not sort_key and 'cat wikilink') or 'cat wikilink sk'; -- make <cfg.messages> key end for _, v in ipairs (z.error_cats_t) do -- append error categories table.insert (render_t, utilities.substitute (cfg.messages[cat_wikilink], {v, sort_key})); end for _, v in ipairs (z.maint_cats_t) do -- append maintenance categories table.insert (render_t, utilities.substitute (cfg.messages[cat_wikilink], {v, sort_key})); end -- for _, v in ipairs (z.prop_cats_t) do -- append properties categories -- table.insert (render_t, utilities.substitute (cfg.messages['cat wikilink'], v)); -- no sort keys -- end end return table.concat (render_t); -- make a big string and done end --[[--------------------------< V A L I D A T E >-------------------------------------------------------------- Looks for a parameter's name in one of several whitelists. Parameters in the whitelist can have three values: true - active, supported parameters false - deprecated, supported parameters nil - unsupported parameters ]] local function validate (name, cite_class, empty) local name = tostring (name); local enum_name; -- parameter name with enumerator (if any) replaced with '#' local state; local function state_test (state, name) -- local function to do testing of state values if true == state then return true; end -- valid actively supported parameter if false == state then if empty then return nil; end -- empty deprecated parameters are treated as unknowns deprecated_parameter (name); -- parameter is deprecated but still supported return true; end if 'tracked' == state then local base_name = name:gsub ('%d', ''); -- strip enumerators from parameter names that have them to get the base name utilities.add_prop_cat ('tracked-param', {base_name}, base_name); -- add a properties category; <base_name> modifies <key> return true; end return nil; end if name:find ('#') then -- # is a cs1|2 reserved character so parameters with # not permitted return nil; end -- replace enumerator digit(s) with # (|last25= becomes |last#=) (mw.ustring because non-Western 'local' digits) enum_name = mw.ustring.gsub (name, '%d+$', '#'); -- where enumerator is last charaters in parameter name (these to protect |s2cid=) enum_name = mw.ustring.gsub (enum_name, '%d+([%-l])', '#%1'); -- where enumerator is in the middle of the parameter name; |author#link= is the oddity if 'document' == cite_class then -- special case for {{cite document}} state = whitelist.document_parameters_t[enum_name]; -- this list holds enumerated and nonenumerated parameters if true == state_test (state, name) then return true; end return false; end if utilities.in_array (cite_class, whitelist.preprint_template_list_t) then -- limited parameter sets allowed for these templates state = whitelist.limited_parameters_t[enum_name]; -- this list holds enumerated and nonenumerated parameters if true == state_test (state, name) then return true; end state = whitelist.preprint_arguments_t[cite_class][name]; -- look in the parameter-list for the template identified by cite_class if true == state_test (state, name) then return true; end return false; -- not supported because not found or name is set to nil end -- end limited parameter-set templates if utilities.in_array (cite_class, whitelist.unique_param_template_list_t) then -- template-specific parameters for templates that accept parameters from the basic argument list state = whitelist.unique_arguments_t[cite_class][name]; -- look in the template-specific parameter-lists for the template identified by cite_class if true == state_test (state, name) then return true; end end -- if here, fall into general validation state = whitelist.common_parameters_t[enum_name]; -- all other templates; all normal parameters allowed; this list holds enumerated and nonenumerated parameters if true == state_test (state, name) then return true; end return false; -- not supported because not found or name is set to nil end --[=[-------------------------< I N T E R _ W I K I _ C H E C K >---------------------------------------------- check <value> for inter-language interwiki-link markup. <prefix> must be a MediaWiki-recognized language code. when these values have the form (without leading colon): [[<prefix>:link|label]] return label as plain-text [[<prefix>:link]] return <prefix>:link as plain-text return value as is else ]=] local function inter_wiki_check (parameter, value) local prefix = value:match ('%[%[(%a+):'); -- get an interwiki prefix if one exists local _; if prefix and cfg.inter_wiki_map[prefix:lower()] then -- if prefix is in the map, needs preceding colon so utilities.set_message ('err_bad_paramlink', parameter); -- emit an error message _, value, _ = utilities.is_wikilink (value); -- extract label portion from wikilink end return value; end --[[--------------------------< M I S S I N G _ P I P E _ C H E C K >------------------------------------------ Look at the contents of a parameter. If the content has a string of characters and digits followed by an equal sign, compare the alphanumeric string to the list of cs1|2 parameters. If found, then the string is possibly a parameter that is missing its pipe. There are two tests made: {{cite ... |title=Title access-date=2016-03-17}} -- the first parameter has a value and whitespace separates that value from the missing pipe parameter name {{cite ... |title=access-date=2016-03-17}} -- the first parameter has no value (whitespace after the first = is trimmed by MediaWiki) cs1|2 shares some parameter names with XML/HTML attributes: class=, title=, etc. To prevent false positives XML/HTML tags are removed before the search. If a missing pipe is detected, this function adds the missing pipe maintenance category. ]] local function missing_pipe_check (parameter, value) local capture; value = value:gsub ('%b<>', ''); -- remove XML/HTML tags because attributes: class=, title=, etc. capture = value:match ('%s+(%a[%w%-]+)%s*=') or value:match ('^(%a[%w%-]+)%s*='); -- find and categorize parameters with possible missing pipes if capture and validate (capture) then -- if the capture is a valid parameter name utilities.set_message ('err_missing_pipe', parameter); end end --[[--------------------------< H A S _ E X T R A N E O U S _ P U N C T >-------------------------------------- look for extraneous terminal punctuation in most parameter values; parameters listed in skip table are not checked ]] local function has_extraneous_punc (param, value) if 'number' == type (param) then return; end param = param:gsub ('%d+', '#'); -- enumerated name-list mask params allow terminal punct; normalize if cfg.punct_skip[param] then return; -- parameter name found in the skip table so done end if value:match ('[,;:]$') then utilities.set_message ('maint_extra_punct'); -- has extraneous punctuation; add maint cat end if value:match ('^=') then -- sometimes an extraneous '=' character appears ... utilities.set_message ('maint_extra_punct'); -- has extraneous punctuation; add maint cat end end --[[--------------------------< H A S _ E X T R A N E O U S _ U R L >------------------------------------------ look for extraneous url parameter values; parameters listed in skip table are not checked ]] local function has_extraneous_url (url_param_t) local url_error_t = {}; check_for_url (url_param_t, url_error_t); -- extraneous url check if 0 ~= #url_error_t then -- non-zero when there are errors table.sort (url_error_t); utilities.set_message ('err_param_has_ext_link', {utilities.make_sep_list (#url_error_t, url_error_t)}); -- add this error message end end --[[--------------------------< C I T A T I O N >-------------------------------------------------------------- This is used by templates such as {{cite book}} to create the actual citation text. ]] local function citation(frame) Frame = frame; -- save a copy in case we need to display an error message in preview mode local config = {}; -- table to store parameters from the module {{#invoke:}} for k, v in pairs( frame.args ) do -- get parameters from the {{#invoke}} frame config[k] = v; -- args[k] = v; -- crude debug support that allows us to render a citation from module {{#invoke:}}; skips parameter validation; TODO: keep? end -- i18n: set the name that your wiki uses to identify sandbox subpages from sandbox template invoke (or can be set here) local sandbox = ((config.SandboxPath and '' ~= config.SandboxPath) and config.SandboxPath) or '/sandbox'; -- sandbox path from {{#invoke:Citation/CS1/sandbox|citation|SandboxPath=/...}} is_sandbox = nil ~= string.find (frame:getTitle(), sandbox, 1, true); -- is this invoke the sandbox module? sandbox = is_sandbox and sandbox or ''; -- use i18n sandbox to load sandbox modules when this module is the sandox; live modules else local pframe = frame:getParent() local styles; cfg = mw.loadData ('Module:Citation/CS1/Configuration' .. sandbox); -- load sandbox versions of support modules when {{#invoke:Citation/CS1/sandbox|...}}; live modules else whitelist = mw.loadData ('Module:Citation/CS1/Whitelist' .. sandbox); utilities = require ('Module:Citation/CS1/Utilities' .. sandbox); validation = require ('Module:Citation/CS1/Date_validation' .. sandbox); identifiers = require ('Module:Citation/CS1/Identifiers' .. sandbox); metadata = require ('Module:Citation/CS1/COinS' .. sandbox); styles = 'Module:Citation/CS1' .. sandbox .. '/styles.css'; utilities.set_selected_modules (cfg); -- so that functions in Utilities can see the selected cfg tables identifiers.set_selected_modules (cfg, utilities); -- so that functions in Identifiers can see the selected cfg tables and selected Utilities module validation.set_selected_modules (cfg, utilities); -- so that functions in Date validataion can see selected cfg tables and the selected Utilities module metadata.set_selected_modules (cfg, utilities); -- so that functions in COinS can see the selected cfg tables and selected Utilities module z = utilities.z; -- table of error and category tables in Module:Citation/CS1/Utilities is_preview_mode = not utilities.is_set (frame:preprocess ('{{REVISIONID}}')); local args = {}; -- table where we store all of the template's arguments local suggestions = {}; -- table where we store suggestions if we need to loadData them local error_text; -- used as a flag local capture; -- the single supported capture when matching unknown parameters using patterns local empty_unknowns = {}; -- sequence table to hold empty unknown params for error message listing for k, v in pairs( pframe.args ) do -- get parameters from the parent (template) frame v = mw.ustring.gsub (v, '^%s*(.-)%s*$', '%1'); -- trim leading/trailing whitespace; when v is only whitespace, becomes empty string if v ~= '' then if ('string' == type (k)) then k = mw.ustring.gsub (k, '%d', cfg.date_names.local_digits); -- for enumerated parameters, translate 'local' digits to Western 0-9 end if not validate( k, config.CitationClass ) then if type (k) ~= 'string' then -- exclude empty numbered parameters if v:match("%S+") ~= nil then error_text = utilities.set_message ('err_text_ignored', {v}); end elseif validate (k:lower(), config.CitationClass) then error_text = utilities.set_message ('err_parameter_ignored_suggest', {k, k:lower()}); -- suggest the lowercase version of the parameter else if nil == suggestions.suggestions then -- if this table is nil then we need to load it suggestions = mw.loadData ('Module:Citation/CS1/Suggestions' .. sandbox); --load sandbox version of suggestion module when {{#invoke:Citation/CS1/sandbox|...}}; live module else end for pattern, param in pairs (suggestions.patterns) do -- loop through the patterns to see if we can suggest a proper parameter capture = k:match (pattern); -- the whole match if no capture in pattern else the capture if a match if capture then -- if the pattern matches param = utilities.substitute (param, capture); -- add the capture to the suggested parameter (typically the enumerator) if validate (param, config.CitationClass) then -- validate the suggestion to make sure that the suggestion is supported by this template (necessary for limited parameter lists) error_text = utilities.set_message ('err_parameter_ignored_suggest', {k, param}); -- set the suggestion error message else error_text = utilities.set_message ('err_parameter_ignored', {k}); -- suggested param not supported by this template v = ''; -- unset end end end if not utilities.is_set (error_text) then -- couldn't match with a pattern, is there an explicit suggestion? if (suggestions.suggestions[ k:lower() ] ~= nil) and validate (suggestions.suggestions[ k:lower() ], config.CitationClass) then utilities.set_message ('err_parameter_ignored_suggest', {k, suggestions.suggestions[ k:lower() ]}); else utilities.set_message ('err_parameter_ignored', {k}); v = ''; -- unset value assigned to unrecognized parameters (this for the limited parameter lists) end end end end args[k] = v; -- save this parameter and its value elseif not utilities.is_set (v) then -- for empty parameters if not validate (k, config.CitationClass, true) then -- is this empty parameter a valid parameter k = ('' == k) and '(empty string)' or k; -- when k is empty string (or was space(s) trimmed to empty string), replace with descriptive text table.insert (empty_unknowns, utilities.wrap_style ('parameter', k)); -- format for error message and add to the list end -- crude debug support that allows us to render a citation from module {{#invoke:}} TODO: keep? -- elseif args[k] ~= nil or (k == 'postscript') then -- when args[k] has a value from {{#invoke}} frame (we don't normally do that) -- args[k] = v; -- overwrite args[k] with empty string from pframe.args[k] (template frame); v is empty string here end -- not sure about the postscript bit; that gets handled in parameter validation; historical artifact? end if 0 ~= #empty_unknowns then -- create empty unknown error message utilities.set_message ('err_param_unknown_empty', { 1 == #empty_unknowns and '' or 's', utilities.make_sep_list (#empty_unknowns, empty_unknowns) }); end local url_param_t = {}; for k, v in pairs( args ) do if 'string' == type (k) then -- don't evaluate positional parameters has_invisible_chars (k, v); -- look for invisible characters end has_extraneous_punc (k, v); -- look for extraneous terminal punctuation in parameter values missing_pipe_check (k, v); -- do we think that there is a parameter that is missing a pipe? args[k] = inter_wiki_check (k, v); -- when language interwiki-linked parameter missing leading colon replace with wiki-link label if 'string' == type (k) and not cfg.url_skip[k] then -- when parameter k is not positional and not in url skip table url_param_t[k] = v; -- make a parameter/value list for extraneous url check end end has_extraneous_url (url_param_t); -- look for url in parameter values where a url does not belong return table.concat ({ frame:extensionTag ('templatestyles', '', {src=styles}), citation0( config, args) }); end --[[--------------------------< E X P O R T E D F U N C T I O N S >------------------------------------------ ]] return {citation = citation}; 79118ee25d3a893b095e8a280156cc50dc140901 Модуль:Demo 828 183 408 2024-05-02T11:40:03Z ruwiki>Vavilexxx 0 исправление Scribunto text/plain local p = {} local getArgs = require('Модуль:Arguments').getArgs local function hasValue(param) if param and param:find('%S') then return true end end --creates a frame object that cannot access any of the parent's args --unless a table containing a list keys of not to inherit is provided function disinherit(frame, onlyTheseKeys) local parent = frame:getParent() or frame local orphan = parent:newChild{} orphan.getParent = parent.getParent --returns nil orphan.args = {} if onlyTheseKeys then local family = {parent, frame} for f = 1, 2 do for k, v in pairs(family[f] and family[f].args or {}) do orphan.args[k] = orphan.args[k] or v end end parent.args = mw.clone(orphan.args) setmetatable(orphan.args, nil) for _, k in ipairs(onlyTheseKeys) do rawset(orphan.args, k, nil) end end return orphan, parent end function p.get(frame, arg, passArgs) local orphan, frame = disinherit(frame, passArgs and {arg or 1}) local code, noWiki, preserve = frame.args[arg or 1] or '' local kill_categories = not frame.args.save_categories local tag, sep if code:match'nowiki' then local placeholder, preserve = ('6'):char(), {} -- We replace "&#125;%-" and "%-&#123;" because of some server bug probably connected to -- [[mw:Parsoid/MediaWiki DOM spec/Language conversion blocks]] and leading to -- =mw.text.unstripNoWiki(mw.getCurrentFrame():preprocess('<nowiki>}-</nowiki>')) -- outputting '&#125;-' instead of "}-", while it's ok with "<nowiki>} -</nowiki>" code = mw.text.unstripNoWiki(code) :gsub('&lt;', '<') :gsub('&gt;', '>') :gsub('&#125;%-', '}-') :gsub('%-&#123;', '-{') if (mw.text.trim(code):match'\n') then tag = 'pre' sep = '' end noWiki = code:gsub('%%', placeholder) for k in noWiki:gmatch('&.-;') do table.insert(preserve, (k:gsub('&', '&amp;'))) noWiki = noWiki:gsub('(&.-;)', '%%%s') end noWiki = mw.text.nowiki(noWiki):format(unpack(preserve)):gsub(placeholder, '%%') end return { source = noWiki or code, output = orphan:preprocess(code) :gsub(kill_categories and '%[%[Категория:.-%]%]' or '', '') :gsub(kill_categories and '%[%[К:.-%]%]' or '', '') :gsub(kill_categories and '%[%[Category:.-%]%]' or '', ''), frame = frame, args = getArgs(frame), tag = tag, sep = sep } end function p.main(frame, demoTable) local show = demoTable or p.get(frame) local args = show.args local yesno = require('Module:Yesno') args.reverse = yesno(args.reverse, false) args.tag = hasValue(args.tag) and args.tag or hasValue(show.tag) and show.tag or "code" args.sep = args.sep or args.br or show.sep args.sep = tonumber(args.sep) and ('<br>'):rep(args.sep or 0) or args.sep or (args.tag == 'pre' and '' or ' → ') if show[args.result_arg] then return show[args.result_arg] end return args.reverse and string.format( '%s%s<%s%s%s>%s</%s>', show.output, args.sep, args.tag, hasValue(args.class) and string.format(' class="%s"', args.class) or '', hasValue(args.style) and string.format(' style="%s"', args.style) or '', show.source, args.tag ) or string.format( '<%s%s%s>%s</%s>%s%s', args.tag, hasValue(args.class) and string.format(' class="%s"', args.class) or '', hasValue(args.style) and string.format(' style="%s"', args.style) or '', show.source, args.tag, args.sep, show.output ) end --passing of args into other module without preprocessing function p.module(frame) local orphan, frame = disinherit(frame, { 'demo_template', 'demo_module', 'demo_module_func', 'demo_main', 'demo_br', 'demo_result_arg', 'demo_save_categories' }) local template = frame.args.demo_template and 'Template:'..frame.args.demo_template local demoFunc = frame.args.demo_module_func or 'main\n' local demoModule = require('Module:' .. frame.args.demo_module)[demoFunc:match('^%s*(.-)%s*$')] frame.args.br, frame.args.result_arg = frame.args.demo_br or frame.args.demo_sep, frame.args.demo_result_arg local kill_categories = not save_categories if demoModule then local named = {insert = function(self, ...) table.insert(self, ...) return self end} local source = {insert = named.insert, '{{', frame.args.demo_template or frame.args.demo_module, '\n'} if not template then source:insert(2, '#invoke:'):insert(4, '|'):insert(5, demoFunc) end local insertNamed = #source + 1 for k, v in pairs(orphan.args) do local nan, insert = type(k) ~= 'number', {v} local target = nan and named or source target:insert'|' if nan then target:insert(k):insert'=':insert'\n' table.insert(insert, 1, #target) end target:insert(unpack(insert)) local nowiki = v:match('nowiki') if nowiki or v:match('{{.-}}') then orphan.args[k] = frame:preprocess(nowiki and mw.text.unstripNoWiki(v) or v) end end source:insert'}}' table.insert(source, insertNamed, table.concat(named)) return p.main(orphan, { source = mw.text.encode(table.concat(source), "<>'|=~"), output = tostring(demoModule(orphan)):gsub(kill_categories and '%[%[Категория:.-%]%]' or '', ''):gsub(kill_categories and '%[%[К:.-%]%]' or '', ''):gsub(kill_categories and '%[%[Category:.-%]%]' or '', ''), frame = frame }) else return "ERROR: Invalid module function: "..demoFunc end end return p 9beaf8f8041a39ae73ba17b2f70609171c4196d3 Шаблон:Действия для страницы/styles.css 10 175 392 2024-05-02T17:22:30Z ruwiki>Stjn 0 fix sanitized-css text/css .ts-tlinks-tlinks { font-weight: normal; float: right; line-height: inherit; } .ts-tlinks-tlinks .mw-editsection-divider { display: inline; } /* [[Категория:Шаблоны:Подстраницы CSS]] */ a003e896d263c29e66d2246b210e5d73e577ea46 Шаблон:Действия для страницы 10 174 390 2024-05-02T17:24:27Z ruwiki>Stjn 0 никаких пиксельных fontsize wikitext text/x-wiki <templatestyles src="Шаблон:Действия для страницы/styles.css" /><div style="{{#ifeq: {{yesno-yes|{{{right|}}}}} | yes || float:none; }}" class="ts-tlinks-tlinks mw-editsection-like plainlinks"><span class="mw-editsection-bracket">[</span><!-- -->{{join|separator=<span class="mw-editsection-divider"> &amp;#124; </span> |1={{#ifexist: {{#rel2abs: {{{lc|}}} }} | {{#ifeq: {{{dislooklink|{{{noview|}}}}}} | yes || [[{{{lc}}}|просмотр]] }} }} |2={{#ifexist: {{#rel2abs: {{{lc|}}} }} | [[Special:EditPage/{{#rel2abs: {{{lc}}} }}|править]] }} |3={{#ifexist: {{#rel2abs: {{{lc|}}} }} | {{#ifeq: {{{dishistlink|{{{nohistory|}}}}}} | yes || [[Special:PageHistory/{{#rel2abs: {{{lc}}} }}|история]] }} }} |4={{#ifexist: {{#rel2abs: {{{lc|}}} }} | | [{{fullurl:{{#rel2abs: {{{lc}}} }}|action=edit&redlink=1}} создать] }} |5={{#ifeq: {{{diswatchlink|{{{nowatch|}}}}}} | yes || [{{fullurl:{{#rel2abs: {{{lc}}} }}|action=watch}} следить] }} |6={{#ifeq: {{{disupdlink|{{{noupdate|}}}}}} | yes || {{очистить кэш|обновить|nocat=1}}</span> }} }}<span class="mw-editsection-bracket">]</span></div><noinclude> {{doc}} </noinclude> 9ee2c9eed92e2ecc9377a7b9486ad8bc214a83d4 Модуль:Wikidata/Medals 828 284 729 2024-05-04T17:24:40Z ruwiki>Putnik 0 импорт списка дубликатов из [[az:Modul:Wikidata/Medals]] Scribunto text/plain local WDS = require( 'Module:WikidataSelectors' ) local moduleDate = require( 'Module:Wikidata/date' ) local awardsOrder = mw.ext.data.get( "Wikidata/awards order.tab" ) local p = {} local config = { --Hide award with key QID if there is a reward with value QID absorption = { Q16675272 = 'Q654471', Q16481808 = 'Q8706404', Q1948730 = 'Q178473', Q1980962 = 'Q208167', Q2032399 = 'Q2046996', Q102183407 = 'Q103819965', Q1262166 = 'Q80589', Q749849 = 'Q1358055', Q4287121 = 'Q4137462', } } --Get string with dates from qualifiers table local function datesFromQualifier( context, options, qualifierId ) local dates = {} local qualifiers = options.qualifiers[ qualifierId ] if qualifiers then for _, qualifier in pairs( qualifiers ) do if qualifier.datavalue then local dateValue = moduleDate.formatDate( context, options, qualifier.datavalue.value ) if dateValue then table.insert( dates, dateValue ) end end end end return table.concat( dates, ', ' ) end --Property function for [[d:Property:P166]] function p.formatProperty( context, options ) if ( not context ) then error( 'context not specified' ); end; if ( not options ) then error( 'options not specified' ); end; if ( not options.entityId ) then error( 'options.entityId missing' ); end; local claims; if options.property then -- TODO: Почему тут может не быть property? claims = context.selectClaims( options, options.property ); end if claims == nil then return '' --TODO error? end -- Обход всех заявлений утверждения и с накоплением оформленых -- предпочтительных заявлений в таблице. local formattedData = {} for i, claim in ipairs( claims ) do if ( claim.mainsnak and claim.mainsnak and claim.mainsnak.datavalue and claim.mainsnak.datavalue.type == 'wikibase-entityid' ) then local valueId = claim.mainsnak.datavalue.value.id local formattedStatement = context.formatStatement( options, claim ) -- здесь может вернуться либо оформленный текст заявления, либо строка ошибки, либо nil if ( formattedStatement and formattedStatement ~= '' ) then formattedStatement = '<span class="wikidata-claim" data-wikidata-property-id="' .. string.upper( options.property ) .. '" data-wikidata-claim-id="' .. claim.id .. '">' .. formattedStatement .. '</span>' table.insert( formattedData, { id = valueId, html = formattedStatement, } ) end end end -- Удаление дублей (медаль + звание -> звание) for i, awardData in ipairs( formattedData ) do local isAbsorptionFound = false if config.absorption[ awardData.id ] then local absorptionAwardId = config.absorption[ awardData.id ] for _, absorptionAwardData in ipairs( formattedData ) do if absorptionAwardData.id == absorptionAwardId then isAbsorptionFound = true break end end end if isAbsorptionFound then table.remove( formattedData, i ) end end -- Сортировка медалей по старшинству local orderedData = {} local lastValue; if ( type (awardsOrder) == 'table' ) then -- Если не отсохла stuctured data for i, awardFields in ipairs( awardsOrder.data ) do local awardOrder = awardFields[ 1 ] if awardOrder == '-' then -- separator if lastValue ~= '-' then table.insert( orderedData, '<br>' ) lastHeight = nil end else for k, awardData in ipairs( formattedData ) do if awardOrder == awardData.id and not awardData.used then table.insert( orderedData, awardData.html ) formattedData[ k ].used = true end end end end end for i, awardData in ipairs( formattedData ) do if not awardData.used then table.insert( orderedData, awardData.html ) end end local lastHeight for i, awardHtml in ipairs( orderedData ) do local height = mw.ustring.match( awardHtml, 'x%d+px' ) if height and lastHeight and height ~= lastHeight then table.insert( orderedData, i, '<br>' ) end lastHeight = height end -- создание текстовой строки со списком оформленых заявлений из таблицы local out = mw.text.listToText( orderedData, options.separator, options.conjunction ) if out ~= '' then if options.before then out = options.before .. out end if options.after then out = out .. options.after end end return out end local function getImageFromProperty( entityId, propertyId ) local imageClaims = WDS.load( entityId, propertyId ) if imageClaims and #imageClaims > 0 then for _, claim in ipairs( imageClaims ) do if claim.type == 'statement' and claim.mainsnak.snaktype == 'value' then return claim.mainsnak.datavalue.value end end end return nil end -- Получение изображения (планки или иконки) и его размера function p.getImageFromEntity( entityId, actualDate ) if type( entityId ) ~= "string" then entityId = entityId.id end local image = nil local size = 'x17px' local border = false -- получение изображения планки из элемента image = getImageFromProperty( entityId, 'P2425' ) if image then border = true end -- получение иконки из элемента if not image then image = getImageFromProperty( entityId, 'P2910' ) if image then size = '40x40px' end end return image, size, border end --Value function for [[d:Property:P166]] function p.formatValue( context, options, statement ) local entityId = statement.id if not entityId then return statement end local label = mw.wikibase.getLabel( entityId ) local image, size, border = p.getImageFromEntity( entityId ) local recipientCategory = '' if not options.nocat and options.nocat ~= '' then recipientCategory = context.extractCategory( { category = 'P7084[P4224:Q24571879]' }, entityId ) if recipientCategory == '' then recipientCategory = context.extractCategory( { category = 'P2517' }, entityId ) end end local dates = '' if options.qualifiers then local startDates = {} dates = datesFromQualifier( context, options, 'P580' ) if dates ~= '' then local endDates = datesFromQualifier( context, options, 'P582' ) if endDates and endDates ~= '' then dates = dates .. ' — ' .. endDates end else dates = datesFromQualifier( context, options, 'P585' ) end if options.qualifiers.P27 then mw.log('>>>>>>>>>>>>>') for _, claim in ipairs( options.qualifiers.P27 ) do if claim and claim.datavalue and claim.datavalue.value and claim.datavalue.value.id then local categoryOptions = { category = 'P7084[P27:' .. claim.datavalue.value.id .. ']' } recipientCategory = recipientCategory .. context.extractCategory( categoryOptions, entityId ) end end end end -- получение ссылки по идентификатору и вывод планки if image then local link = mw.wikibase.getSitelink( entityId ) local out = '[[File:' .. image if border == true then out = out .. '|border' end out = out .. '|' .. size .. '|link=' -- получение ссылки из родительского элемента -- для степеней обычно только одна общая статья if not link then local partOfClaims = WDS.load( entityId, 'P361' ) -- часть от if not partOfClaims or #partOfClaims == 0 then partOfClaims = WDS.load( entityId, 'P279' ) -- подкласс от end if partOfClaims and #partOfClaims > 0 then for _, claim in ipairs( partOfClaims ) do if claim.type == 'statement' and claim.mainsnak.snaktype == 'value' then link = mw.wikibase.getSitelink( claim.mainsnak.datavalue.value.id ) if link then break end end end end end if link then out = out .. link else out = out .. 'd:' .. entityId end if label then out = out .. '|' .. label end out = out .. ']]' out = out .. recipientCategory return out end local out = context.formatValueDefault( context, options, statement ) if out and out ~= '' then if dates ~= '' then out = out .. ' (' .. dates .. ')' end return '<span style="display:inline-block; text-align:left>' .. out .. recipientCategory .. '</span>' end return '' end --Table for documentation function p.renderDoc() local out = {} for i, awardFields in ipairs( awardsOrder.data ) do local awardId = awardFields[ 1 ] local link = '[[d:' .. awardId .. '|' .. awardId .. ']]' if i == 351 then -- limits table.insert( out, '| … || … || … || … || …' ) elseif i > 351 and i < #awardsOrder.data then -- do nothing elseif awardId == '-' then -- separator table.insert( out, '|' .. i .. '|| colspan="3" | ----' ) else local image, size, border = p.getImageFromEntity( awardId ) if image then image = '[[File:' .. image if border == true then image = image .. '|border' end image = image .. '|' .. size .. ']]' else image = '' end local label = mw.wikibase.getLabel( awardId ) or '' local article = mw.wikibase.getSitelink( awardId ) if article then if label == '' then label = article end label = '[[' .. article .. '|' .. label .. ']]' end local countryStatements = mw.wikibase.getBestStatements( awardId, 'P17' ) local countries = {} if countryStatements then for _, statement in ipairs( countryStatements ) do if statement.mainsnak.datavalue and statement.mainsnak.datavalue.type == 'wikibase-entityid' then local countryId = statement.mainsnak.datavalue.value.id table.insert( countries, mw.wikibase.getLabel( countryId ) ) end end end table.insert( out, '|' .. i .. '||' .. link .. '||' .. image .. '||' .. label .. '||' .. table.concat( countries, ', ' ) ) end end return '{| class="wikitable"\n' .. '! # !! Элемент !! Планка !! Название !! Государство\n|-\n' .. table.concat( out, '\n|-\n' ) .. '\n|}' end return p 4de64e0e2181e8a4487f3e18da893fca9f92660d Шаблон:OnLua 10 227 505 2024-05-07T19:08:37Z ruwiki>MBH 0 MBH переименовал страницу [[Шаблон:OnLua]] в [[Шаблон:Lua]] wikitext text/x-wiki #перенаправление [[Шаблон:Lua]] b72371e7ae22239863c474a78238171c2bd94c7e Шаблон:Lua 10 230 511 2024-05-07T19:08:37Z ruwiki>MBH 0 MBH переименовал страницу [[Шаблон:OnLua]] в [[Шаблон:Lua]] wikitext text/x-wiki <includeonly>{{ombox | small = yes | style = width:23em; | image = [[Файл:Lua-logo-nolabel.svg|40px|alt=|link=]] | text = {{replace|Этот шаблон {{#if: {{{partly|}}} | частично }} реализован на основе [[Lua]]{{#if:{{{module2|}}}{{{tech2|}}}|&#58;<br><ul><li>}}{{#if:{{{1|}}}{{{tech|}}}|&#32;с использованием {{{tech|{{#if:{{{2|}}}|функции <code>{{#if:{{{line|}}}|[[Module:{{{1}}}#L-{{{line}}}|{{{2}}}()]]|[[{{{funcref|Module:{{{1}}}#{{{2}}}}}}|{{{2}}}()]]}}</code> из&#32;}}{{#if:{{{1|}}}|модуля [[Module:{{{1}}}|{{{1}}}]]}}}}};}}<!-- -->{{#invoke:Transclude|npc|OnLua/Строка| module= |function= |tech= |line= }}.|;.|.}}{{#if:{{{module2|}}}{{{tech2|}}}|</ul>}} {{#if:{{{1|}}}{{{tech|}}}{{{module1|}}}{{{tech1|}}}||<div class="error"><small>'''Не указано название использующегося модуля!'''</small></div>}} }}{{#ifeq:{{SUBPAGENAME}}|{{{doc|doc}}}||{{#if:{{{nocat|}}}||[[Категория:Шаблоны, использующие Scribunto]]{{#if:{{{1|}}}{{{tech|}}}{{{module1|}}}{{{tech1|}}}||[[Категория:Шаблоны, использующие Lua, без указания модуля]]}}}}}}</includeonly><noinclude>{{doc}}</noinclude> f1fdaa87edb15d61e23e98f6e25d171a975e10eb Шаблон:OnLua/Строка 10 228 507 2024-05-07T19:08:38Z ruwiki>MBH 0 MBH переименовал страницу [[Шаблон:OnLua/Строка]] в [[Шаблон:Lua/Строка]] wikitext text/x-wiki #перенаправление [[Шаблон:Lua/Строка]] d7f869ccc7a7efc800399fce32bc75e0f91066de Шаблон:Lua/Строка 10 231 513 2024-05-07T19:08:38Z ruwiki>MBH 0 MBH переименовал страницу [[Шаблон:OnLua/Строка]] в [[Шаблон:Lua/Строка]] wikitext text/x-wiki <includeonly>{{#if: {{{module|}}}{{{tech|}}} | <li>с использованием {{#if: {{{tech|}}} | {{{tech}}} | {{#if: {{{function|}}} | {{#if: {{{module|}}} | функции <code>{{#if: {{{line|}}} | [{{fullurl: Module:{{{module}}}|action=edit}}#mw-ce-l{{{line}}} {{{function}}}()] | [[{{{funcref|Module:{{{module}}}#{{{function}}}}}} | {{{function}}}()]]}}</code> из&#32;}}}}{{#if: {{{module|}}} | модуля [[Module:{{{module}}} | {{{module}}}]]}}}};}}</includeonly><noinclude>[[Категория:Шаблоны:Подстраницы шаблонов]]</noinclude> 5a35837338c2daee2d240a8e5335e8fec8e7d87e Шаблон:Wikidata/p569 10 269 699 2024-05-08T19:10:13Z ruwiki>Dima st bk 0 |suppressAge={{{suppress age|}}} с викиданных wikitext text/x-wiki {{#switch:{{{1|}}}|-=|={{#invoke:Wikidata|formatStatements|property=p569|claim-module=Wikidata/date|claim-function=formatDateOfBirthClaim|nocat={{{nocat|}}}{{NAMESPACE}}|suppressAge={{{suppress age|}}}}}|{{#invoke:Infocards|dateOfBirth|{{{1|}}}|{{{2|}}}|suppressAge={{wikidata|P570|plain=true}}{{{suppress age|}}}|nocat={{{nocat|}}}{{NAMESPACE}}}}}}<noinclude>{{doc}}</noinclude> 9643ab18fcd322831b72e38658b58c6b94a914e2 Шаблон:Установлена проверка на неизвестные параметры 10 296 753 2024-05-10T14:11:21Z ruwiki>Abiyoyo 0 категория для шаблонов отдельно, для самих категорий отдельно wikitext text/x-wiki {{ombox |name = Установлена проверка на неизвестные параметры |text = В этом шаблоне установлена [[Модуль:Check for unknown parameters|проверка на неизвестные параметры]], добавляющая страницы в {{c|{{#if:{{{категория|}}}|{{{категория|}}}|Страницы с неизвестными параметрами шаблона {{ROOTPAGENAME}}}}|В}}. |type = notice }}<includeonly>{{no-doc|[[Категория:Шаблоны с установленной проверкой на неизвестные параметры]]{{#ifexist: Категория:{{#if:{{{категория|}}}|{{{категория|}}}|Страницы с неизвестными параметрами шаблона {{ROOTPAGENAME}}}} || [[Категория:Шаблоны с установленной проверкой на неизвестные параметры и несуществующей категорией]] }}|nocat={{{nocat|}}}}}</includeonly><noinclude>{{doc-inline}} См. [[Модуль:Check for unknown parameters]] и [[:Категория:Википедия:Неизвестные параметры шаблонов]]. Добавляет {{Категория с размером|Шаблоны с установленной проверкой на неизвестные параметры и несуществующей категорией}}. [[Категория:Шаблоны:Предупреждения]] [[Категория:Шаблоны:Для документирования шаблонов]] {{doc-end}} </noinclude> cd47e06eec53b65393adba1f3143d6cd3d6cc54c Модуль:TemplateDataDoc 828 299 759 2024-05-15T20:45:48Z ruwiki>Abiyoyo 0 для персокарточек Scribunto text/plain require( 'strict' ); local docSubPage = mw.message.new( 'Templatedata-doc-subpage' ):plain(); local p = {}; local lastNumber = 0; -- Enable/disable additional spacing for block-formatted templates local formatBlockSpaces = true; -- Params that should not be shown in code local deprecatedParams = { 'nocat', 'from', 'nocoord', 'nocatcoord', 'Автооформление заголовка', 'автооформление заголовка', 'Ширина', 'ширина', 'Ширина изображения', 'ширина изображения', 'Ширина логотипа', 'ширина логотипа', 'Ширина автографа', 'ширина автографа', }; local noDocNote = 'TemplateDataDoc: Запишите страницу для отображения заполненного шаблона.'; function p.processJson( json ) local status, data = pcall( mw.text.jsonDecode, json ); if status == false then return nil; end if not data[ 'paramOrder' ] then data[ 'paramOrder' ] = {}; for paramName, paramData in pairs( data[ 'params' ] ) do table.insert( data[ 'paramOrder' ], paramName ); end end for _, param in ipairs( deprecatedParams ) do if data[ 'params' ][ param ] ~= nil then data[ 'params' ][ param ][ 'deprecated' ] = '-'; end end return data; end function p.getTemplateData( pageName ) local title = mw.title.makeTitle( 0, pageName ); if not title or not title.exists then return false end local content = title:getContent() if not content then return false; end; local json = mw.ustring.match( content, '<[Tt]emplate[Dd]ata%s*>(.*)</[Tt]emplate[Dd]ata%s*>' ); if not json then return nil; end return p.processJson( json ) end function p.getValue( data, key ) if data[ key ] then return data[ key ]; end -- Numbered keys return as numbers local nkey = tonumber( key ); if nkey ~= nil and data[ nkey ] then return data[ nkey ]; end return {}; end -- See https://phabricator.wikimedia.org/diffusion/ETDA/browse/master/Specification.md?as=remarkup -- We need a global format value for the 'block' and 'inline': [[phab:T205438]] function p.convertFormatString( rawTemplateFormat ) local formatType = rawTemplateFormat or 'inline'; local templateFormat = formatType; local isBlockFormatted = false; if formatType == 'block' then templateFormat = '{{_\n| _ = _\n}}'; isBlockFormatted = true; elseif formatType == 'inline' then templateFormat = '{{_|_=_}}'; end return templateFormat, isBlockFormatted, formatType; end function p.getFormatParts( rawTemplateFormat, templateName ) local templateFormat, isBlockFormatted, formatType = p.convertFormatString( rawTemplateFormat ); local nameFormat = mw.ustring.match( templateFormat, '^[^|]+' ); local paramKeyFormat = mw.ustring.match( templateFormat, '%|[^=]+=' ); local paramValueFormat = mw.ustring.match( templateFormat, '=[^}]+' ); paramValueFormat = mw.ustring.sub( paramValueFormat, 2 ); local endFormat = mw.ustring.match( templateFormat, '%}%}.*$' ); local startFormat = mw.ustring.gsub( nameFormat, '_', templateName ); return isBlockFormatted, formatType, startFormat, endFormat, paramKeyFormat, paramValueFormat; end function p.formatKeyValue( key, parameterData, formatData ) if parameterData[ 'deprecated' ] then return ''; end local args = formatData.args; local parameterName = key; local nkey = tonumber( key ); -- Add additional spacing to string keys if formatBlockSpaces and formatData.parameterLength and formatData.formatType ~= 'inline' and ( nkey == nil or lastNumber ~= nkey - 1 ) then while mw.ustring.len( key ) < formatData.parameterLength do key = key .. ' '; end end -- Remove numbering for adjacent numbered keys if nkey ~= nil and lastNumber == nkey - 1 then key = ''; lastNumber = nkey; end local value = ''; if formatData.valueKey == 'example' and parameterData[ 'example' ] then -- Example value = parameterData[ 'example' ]; else if formatData.valueKey == 'description' and parameterData[ 'description' ] then -- Description value = parameterData[ 'description' ]; if value ~= '' then value = '&lt;!-- ' .. value .. ' --&gt;'; end elseif parameterData[ 'autovalue' ] then -- Autovalue value = parameterData[ 'autovalue' ]; end if args[ '$' .. parameterName ] and args[ '$' .. parameterName ] ~= '' then -- Custom values from template call value = args[ '$' .. parameterName ]; end end local formattedKey = mw.ustring.gsub( formatData.paramKeyFormat, '_+', key, 1 ); if key == '' then formattedKey = mw.ustring.gsub( formattedKey, '=', '' ); end return formattedKey .. mw.ustring.gsub( formatData.paramValueFormat, '_', value, 1 ); end function p.generateBlankCode( templateData, templateName, args ) if templateData == false then return '{{' .. templateName .. '}}'; end local parameterLength = 0; for i, parameterName in ipairs( templateData[ 'paramOrder' ] ) do local parameterData = p.getValue( templateData[ 'params' ], parameterName ); if not parameterData[ 'deprecated' ] then local length = mw.ustring.len( parameterName ); if length > parameterLength then parameterLength = length; end end end local isBlockFormatted, formatType, startFormat, endFormat, paramKeyFormat, paramValueFormat = p.getFormatParts( templateData[ 'format' ], templateName ); local out = startFormat; lastNumber = 0; for i, parameterName in ipairs( templateData[ 'paramOrder' ] ) do local parameterData = p.getValue( templateData[ 'params' ], parameterName ); if parameterData[ 'inherits' ] then parameterData = p.getValue( templateData[ 'params' ], parameterData[ 'inherits' ] ); end out = out .. p.formatKeyValue( parameterName, parameterData, { args = args, valueKey = ( args[ 'description' ] and 'description' or nil ), formatType = formatType, isBlockFormatted = isBlockFormatted, parameterLength = parameterLength, paramKeyFormat = paramKeyFormat, paramValueFormat = paramValueFormat, } ); end return out .. endFormat; end function p.generateBlank( frame ) local frame = mw.getCurrentFrame(); local getArgs = require( 'Module:Arguments' ).getArgs; local args = getArgs( frame ); local templateName = frame.args[ 1 ]; table.remove( args, 1 ); local docPage = 'Template:' .. templateName .. '/' .. docSubPage; local templateData = p.getTemplateData( docPage ); local out = p.generateBlankCode( templateData, templateName, args ); local previewNote = '' if templateData == false and frame:preprocess('{{REVISIONID}}') == '' then previewNote = '<div class="warningbox">' .. noDocNote .. '</div>'; end return previewNote .. frame:extensionTag{ name = 'pre', content = out }; end function p.generateExampleCode( templateData, templateName, args ) if templateData == false then return '{{' .. templateName .. '}}'; end local parameterLength = 0; for i, parameterName in ipairs( templateData[ 'paramOrder' ] ) do local parameterData = p.getValue( templateData[ 'params' ], parameterName ); if parameterData[ 'example' ] and not parameterData[ 'deprecated' ] then local length = mw.ustring.len( parameterName ); if length > parameterLength then parameterLength = length; end end end local isBlockFormatted, formatType, startFormat, endFormat, paramKeyFormat, paramValueFormat = p.getFormatParts( templateData[ 'format' ], templateName ); local out = startFormat; lastNumber = 0; for i, parameterName in ipairs( templateData[ 'paramOrder' ] ) do local parameterData = p.getValue( templateData[ 'params' ], parameterName ); if parameterData[ 'inherits' ] then parameterData = p.getValue( templateData[ 'params' ], parameterData[ 'inherits' ] ); end if parameterData[ 'example' ] then out = out .. p.formatKeyValue( parameterName, parameterData, { args = args, valueKey = 'example', formatType = formatType, isBlockFormatted = isBlockFormatted, parameterLength = parameterLength, paramKeyFormat = paramKeyFormat, paramValueFormat = paramValueFormat, } ); end end return out .. endFormat; end function p.generateExample( frame ) local frame = mw.getCurrentFrame(); local args = frame.args; local templateName = frame.args[ 1 ]; local docPage = 'Template:' .. templateName .. '/' .. docSubPage; local templateData = p.getTemplateData( docPage ); local out = p.generateExampleCode( templateData, templateName, args ); local previewNote = '' if templateData == false and frame:preprocess('{{REVISIONID}}') == '' then previewNote = '<div class="warningbox">' .. noDocNote .. '</div>'; end return previewNote .. frame:preprocess( out ) .. frame:extensionTag{ name = 'pre', content = out }; end return p; 53670b81abac0bc22d720fbe984944dcd709da7c Шаблон:Скрытый блок/styles.css 10 197 440 2024-05-16T20:54:54Z ruwiki>Putnik 0 поддержка тёмной темы sanitized-css text/css .ts-Скрытый_блок { margin: 0; overflow: hidden; border-collapse: collapse; box-sizing: border-box; font-size: 95%; } .ts-Скрытый_блок-title { text-align: center; font-weight: bold; line-height: 1.6em; min-height: 1.2em; } .ts-Скрытый_блок .mw-collapsible-content { overflow-x: auto; overflow-y: hidden; clear: both; } .ts-Скрытый_блок::before, .ts-Скрытый_блок .mw-collapsible-toggle { padding-top: .1em; width: 6em; font-weight: normal; font-size: calc(90% / 0.95); } .ts-Скрытый_блок-rightHideLink .mw-collapsible-toggle { float: right; text-align: right; } .ts-Скрытый_блок-leftHideLink .mw-collapsible-toggle { float: left; text-align: left; } .ts-Скрытый_блок-gray { padding: 2px; border: 1px solid var(--border-color-base, #a2a9b1); } .ts-Скрытый_блок-transparent { border: none; } .ts-Скрытый_блок-gray .ts-Скрытый_блок-title { background: var(--background-color-neutral, #eaecf0); padding: .1em 6em; padding-right: 0; } .ts-Скрытый_блок-transparent .ts-Скрытый_блок-title { background: transparent; padding: .1em 5.5em; padding-right: 0; } .ts-Скрытый_блок-gray .mw-collapsible-content { padding: .25em 1em; } .ts-Скрытый_блок-transparent .mw-collapsible-content { padding: .25em 0; } .ts-Скрытый_блок-gray.ts-Скрытый_блок-rightHideLink .mw-collapsible-toggle { padding-right: 1em; } .ts-Скрытый_блок-transparent.ts-Скрытый_блок-rightHideLink .mw-collapsible-toggle { padding-right: 0; } .ts-Скрытый_блок-gray.ts-Скрытый_блок-leftHideLink .mw-collapsible-toggle { padding-left: 1em; } .ts-Скрытый_блок-transparent.ts-Скрытый_блок-leftHideLink .mw-collapsible-toggle { padding-left: 0; } .ts-Скрытый_блок-gray.ts-Скрытый_блок-rightHideLink .ts-Скрытый_блок-title-leftTitle { padding-left: 1em; } .ts-Скрытый_блок-gray.ts-Скрытый_блок-leftHideLink .ts-Скрытый_блок-title-leftTitle { padding-left: 6.5em; } .ts-Скрытый_блок-gray.ts-Скрытый_блок-leftHideLink .ts-Скрытый_блок-title-rightTitle { padding-right: 1em; } .ts-Скрытый_блок-transparent.ts-Скрытый_блок-rightHideLink .ts-Скрытый_блок-title-rightTitle, .ts-Скрытый_блок-transparent.ts-Скрытый_блок-rightHideLink .ts-Скрытый_блок-title-leftTitle { padding-left: 0; } .ts-Скрытый_блок-transparent.ts-Скрытый_блок-leftHideLink .ts-Скрытый_блок-title-rightTitle, .ts-Скрытый_блок-transparent.ts-Скрытый_блок-leftHideLink .ts-Скрытый_блок-title-leftTitle { padding-right: 0; } .ts-Скрытый_блок + .ts-Скрытый_блок, .ts-Скрытый_блок + link + .ts-Скрытый_блок { border-top-style: hidden; } /* [[Категория:Шаблоны:Подстраницы CSS]] */ 41e605b205f412804b46a4c6c5dd51a71c6a59ca Шаблон:Карточка/doc 10 226 503 2024-05-17T22:19:21Z ruwiki>Abiyoyo 0 дополнение wikitext text/x-wiki {{docpage}} {{OnLua|Infobox|renderLines|module2=Transclude|function2=npc}} {{СИШ}} Это меташаблон для создания [[Википедия:Шаблоны-карточки|шаблонов-карточек]]. == Параметры == === Служебные === ; имя: Имя шаблона, необходимое для корректной работы служебных инструментов на всех страницах, где используется шаблон. Для простоты можно использовать <code><nowiki>{{subst:PAGENAME}}</nowiki></code>. ; автозаголовки: Указание «да» приводит к автоматическому скрытию заголовков, после которых, вплоть до следующего заголовка, все поля пусты. Возможно использовать фиктивные заголовки «-» для прерывания области скрытия. Будет работать некорректно, если требуется указать два заголовка подряд — например, при использовании многоуровневых заголовков. В этом случае рекомендуется явно указать «нет» на случай смены значения по умолчанию с «нет» на «да». ; from: Указывается элемент Викиданных, из которого берётся информация. === Основные === ; вверху: Текст, отображаемый вверху таблицы. Обычно это название предмета статьи. ; вверху2: Дополнительный текст, отображаемый вверху таблицы. Обычно используется для оригинального названия. ; вверху3: Дополнительный текст, отображаемый вверху таблицы. ; изображение: Изображение, которое будет отображено под основным заголовком в правой части таблицы (правее заголовков/списков). Параметр ''изображение'' допускает стандартный викикод для отображения. Для разных типов параметра можно использовать {{tl|Форматирование изображения}}. Обычно предпочтительнее использовать код <code><nowiki>{{wikidata|P18|{{{изображение|}}}|caption={{{описание изображения|}}}}}</nowiki></code>. ; подпись: Подпись под изображением. Отображается только в том случае, если задано изображение. При использовании {{tlp|wikidata|P18}} не заполняется. ; изображение2: Дополнительное изображение. ; изображение3: Дополнительное изображение. ; заголовок<sub>n</sub>: Используется для создания заголовков в ряду. Этот и следующие 2 параметра работают при n≥1. ; метка<sub>n</sub>: Используется для подписи текста ; текст<sub>n</sub>: Используется для принятия параметров в специализированных шаблонах-карточках. ; блок<sub>n</sub>: Технический параметр, используется для вставки блоков, заключённых в &#60;tr&#62;, таких как {{t|карточка/блок}}. ; викиданные<sub>n</sub>: Подставляет значение из указанного параметра [[Википедия:Викиданные|Викиданных]] в поле текста, если текст в этой строке определён. Если в поле текста передано значение <code>-</code>, то значение из Викиданных будет скрыто. ; внизу ; внизу<sub>n</sub>: Ячейка во всю ширину таблицы, располагающаяся внизу тела шаблона (то есть под заголовками/метками и текстом). === Стили === ; цвет: Применяется для автоматической раскраски полей «вверху», «внизу» и заголовков через CSS при помощи цветовых тем, имеющихся в шаблоне {{t|Цвет}} ; стиль_тела: Применяется ко всей карточке, обычно используется для указания её ширины, например, <code>width:23em;</code> ; стиль_вверху: Применяется к полю «вверху», например, для указания цвета фона или изменения размера шрифта: <code>font-size:medium;</code> ; стиль_вверху<sub>n</sub>: Используется для изменения стиля дополнительного текста вверху таблицы, например, чтобы убрать курсивное начертание: <code>font-style:normal;</code> ; стиль_изображения: Применяется к ячейке, в которой располагается изображение и его описание ; стиль_изображения<sub>n</sub>: Применяется к ячейке, в которой располагается дополнительное изображение ; стиль_подписи: Применяется к подписи изображения ; стиль_заголовков: С помощью этого стиля можно настроить отображение заголовков, в частности, указать цвет фона: <code>background: #a3eea3;</code> ; стиль_заголовка<sub>n</sub>: Применяется к конкретному заголовку в строке n ; стиль_меток: Применяется к меткам ; стиль_метки<sub>n</sub>: Применяется к конкретной метке в строке n ; стиль_текста: Применяется к тексту ; стиль_текста<sub>n</sub>: Применяется к конкретному тексту в строке n ; стиль_внизу: Эти стили применяются не только в первому ''внизу'', но и ко всем остальным — в отличие от ''стиль_вверху''. ; стиль_внизу<sub>n</sub>: CSS-стили, которые должны быть применены к нижним (указанными параметрами ''внизу'' и ''внизу<sub>n</sub>'') ячейкам. == Возможности == === Сдвоенные ячейки === Если для параметра <code>текст<sub>n</sub></code> значение <code>метка<sub>n</sub></code> не определено, то <code>текст<sub>n</sub></code> автоматически расширяется до 2 ячеек. Для выравнивания по левой стороне можно использовать следующий код: <pre><nowiki> |текст2 = {{{параметр|}}} |стиль_текста2 = text-align:left; </nowiki></pre> === Необязательные ячейки === Ряд с меткой, но без текста не будет отображён. Это позволяет легко создавать необязательные параметры в специализированных шаблонах-карточках. Для создания опциональной ячейки используйте параметр следующим образом: <pre><nowiki> |метка5 = Население |текст5 = {{{население|}}} </nowiki></pre> Таким образом, если параметр <code>население</code> не будет определён, строка «Население» не будет отображена. === Необязательные заголовки === Таким же образом можно организовать необязательные заголовки. Следующий пример будет выводить заголовок «Структура», если задан хотя бы один из параметров <code>содержимое</code>, <code>размещение</code>: <pre><nowiki> |заголовок5 = {{#if:{{{содержимое|}}}{{{размещение|}}}|Структура}} |метка6 = Содержимое |текст6 = {{{содержимое|}}} |метка7 = Размещение |текст7 = {{{размещение|}}} </nowiki></pre> Если есть заголовокN, то текстN и меткаN игнорируются. Если нет заданного заголовкаN, то показываются текстN и меткаN. {| |- |<pre><nowiki> |заголовок1 = {{{заголовок1|}}} |метка1 = {{{метка1|}}} |текст1 = {{{текст1|}}} </nowiki></pre> |} {| |- |<pre><nowiki> |заголовок1 = заголовок_текст |метка1 = метка_текст |текст1 = текст_текст </nowiki></pre> | {| class="wikitable" |- ! заголовок_текст |} |<pre><nowiki> |заголовок1 = |метка1 = метка_текст |текст1 = текст_текст </nowiki></pre> | {| class="wikitable" |- | метка_текст|| текст_текст |} |} === Оформление параметров === Для оформления параметра можно использовать [[Википедия:Функции парсера##if|функцию парсера «#if»]]. Например, следующие строки добавят к параметру <code>текст6</code> подпись кг, если этот параметр определён: <pre><nowiki> |метка6 = Масса |текст6 = {{#if:{{{масса|}}} |{{{масса}}} кг}} </nowiki></pre> А расстановку ссылок на страницы можно организовать с помощью «[[Википедия:Функции парсера##switch:|#switch]]», например: <pre><nowiki> |метка6 = Раса |текст6 = {{#switch:{{{раса|}}} |Европеоиды = [[Европеоидная раса|Европеоиды]] |Негроиды = [[Негроидная раса|Негроиды]] |Монголоиды = [[Монголоидная раса|Монголоиды]] |{{{раса|}}} }} </nowiki></pre> == Пустой шаблон == <pre> {{Карточка |имя = {{subst:PAGENAME}} |автозаголовки = да |стиль_вверху = |стиль_заголовков = |стиль_внизу = |вверху = |вверху2 = |изображение = |заголовок1 = |метка2 = |текст2 = |викиданные2 = |метка3 = |текст3 = |викиданные3 = |метка4 = |текст4 = |викиданные4 = |метка5 = |текст5 = |викиданные5 = |метка6 = |текст6 = |викиданные6 = |метка7 = |текст7 = |викиданные7 = |метка8 = |текст8 = |викиданные8 = |метка9 = |текст9 = |викиданные9 = |метка10 = |текст10 = |викиданные10 = ... |меткаN = |текстN = |викиданныеN = |внизу = }}<noinclude> {{doc}} </noinclude></pre> {{скрытый|Заголовок=11-20|Содержание=<pre> |метка11 = |текст11 = |викиданные11 = |метка12 = |текст12 = |викиданные12 = |метка13 = |текст13 = |викиданные13 = |метка14 = |текст14 = |викиданные14 = |метка15 = |текст15 = |викиданные15 = |метка16 = |текст16 = |викиданные16 = |метка17 = |текст17 = |викиданные17 = |метка18 = |текст18 = |викиданные18 = |метка19 = |текст19 = |викиданные19 = |метка20 = |текст20 = |викиданные20 = </pre>}} {{скрытый||Заголовок=21-30|Содержание=<pre> |метка21 = |текст21 = |викиданные21 = |метка22 = |текст22 = |викиданные22 = |метка23 = |текст23 = |викиданные23 = |метка24 = |текст24 = |викиданные24 = |метка25 = |текст25 = |викиданные25 = |метка26 = |текст26 = |викиданные26 = |метка27 = |текст27 = |викиданные27 = |метка28 = |текст28 = |викиданные28 = |метка29 = |текст29 = |викиданные29 = |метка30 = |текст30 = |викиданные30 = </pre>}} {{скрытый||Заголовок=31-40|Содержание=<pre> |метка31 = |текст31 = |викиданные31 = |метка32 = |текст32 = |викиданные32 = |метка33 = |текст33 = |викиданные33 = |метка34 = |текст34 = |викиданные34 = |метка35 = |текст35 = |викиданные35 = |метка36 = |текст36 = |викиданные36 = |метка37 = |текст37 = |викиданные37 = |метка38 = |текст38 = |викиданные38 = |метка39 = |текст39 = |викиданные39 = |метка40 = |текст40 = |викиданные40 = </pre>}} {{скрытый||Заголовок=41-50|Содержание=<pre> |метка41 = |текст41 = |викиданные41 = |метка42 = |текст42 = |викиданные42 = |метка43 = |текст43 = |викиданные43 = |метка44 = |текст44 = |викиданные44 = |метка45 = |текст45 = |викиданные45 = |метка46 = |текст46 = |викиданные46 = |метка47 = |текст47 = |викиданные47 = |метка48 = |текст48 = |викиданные48 = |метка49 = |текст49 = |викиданные49 = |метка50 = |текст50 = |викиданные50 = </pre>}} {{скрытый||Заголовок=51-60|Содержание=<pre> |метка51 = |текст51 = |викиданные51 = |метка52 = |текст52 = |викиданные52 = |метка53 = |текст53 = |викиданные53 = |метка54 = |текст54 = |викиданные54 = |метка55 = |текст55 = |викиданные55 = |метка56 = |текст56 = |викиданные56 = |метка57 = |текст57 = |викиданные57 = |метка58 = |текст58 = |викиданные58 = |метка59 = |текст59 = |викиданные59 = |метка60 = |текст60 = |викиданные60 = </pre>}} == Примерный шаблон для карточки персоны == <pre>{{Карточка |имя = {{subst:PAGENAME}} |автозаголовки = да |стиль_вверху = |стиль_заголовков = |стиль_внизу = |вверху = {{карточка/имя|{{{имя|}}}}} |вверху2 = {{карточка/оригинал имени|{{{оригинал имени|}}}}} |изображение = {{wikidata|p18|{{{фото|}}}|caption={{{описание изображения|}}}|size={{{ширина|}}}}} |метка1 = Имя при рождении |текст1 = {{{имя при рождении|}}} |викиданные1 = p1477 |метка2 = Дата рождения |текст2 = {{wikidata/p569|{{{дата рождения|}}}|{{{дата смерти|}}}}} |метка3 = Место рождения |текст3 = {{{место рождения|}}} |викиданные3 = p19 |метка4 = Дата смерти |текст4 = {{wikidata/p570|{{{дата смерти|}}}|{{{дата рождения|}}}}} |метка5 = Место смерти |текст5 = {{{место смерти|}}} |викиданные5 = p20 |метка6 = Гражданство |текст6 = {{{гражданство|}}} |викиданные6 = p27 |метка7 = Сценические имена / Прозвище |текст7 = {{{прозвище|}}} |викиданные7 = p1449 |заголовок8 = {{wikidata|p856|{{{сайт|}}}}} |внизу = {{карточка/Викисклад|{{{викисклад|}}}}} }}</pre> Шаблоны {{tl|wikidata/p569}} и {{tl|wikidata/p570}} работают с датами по юлианскому календарю следующим образом: * <code>13.5.1801 (1)</code> будет отображено как [[13 мая|1 (13) мая]] [[1801 год|1801]]; * <code>12.6.1801 (31.5)</code> будет отображено как 31 мая ([[12 июня]]) [[1801 год|1801]]; * <code>12.1.1802 (31.12.1801)</code> будет отображено как 31 декабря 1801 ([[12 января]] [[1802 год|1802]]). == Отслеживающие категории, подставляемые шаблоном == {{Дерево категорий|Отслеживающие категории:Шаблон:Карточка||1|title=}} == См. также == * [[Википедия:Шаблоны-карточки]] * {{t|Универсальная карточка}} * {{t|Навигационная таблица}} — для создания горизонтальных навигационных таблиц (предпочтительнее вертикальных, иногда делаемых на карточке) * [[:Категория:Шаблоны:Подстраницы шаблона Карточка|Подстраницы шаблона Карточка]] * [[Участник:Jack who built the house/alignTemplateParameters.js]] {{Подстраницы шаблона Карточка}} <includeonly> [[Категория:Шаблоны-карточки|*]] [[Категория:Шаблоны:Мета-шаблоны]] </includeonly> f1b3e8ad443b38b993ae6112a8adda8827efe76f Шаблон:Дерево категорий 10 229 509 2024-05-17T22:35:29Z ruwiki>QBA-bot 0 Защитил страницу [[Шаблон:Дерево категорий]]: критический шаблон или модуль (каскадная защита) ([Редактирование=только автоподтверждённые] (бессрочно) [Переименование=только автоподтверждённые] (бессрочно)) wikitext text/x-wiki <div>{{{title|'''Дерево категорий'''}}} {{#tag: categorytree| {{#if:{{{1|}}}|{{{1}}}|{{PAGENAME}}}} | mode = {{#if:{{{2}}}|"{{#ifeq:{{{2}}}|всё|all|{{#ifeq:{{{2}}}|страницы|pages|{{#ifeq:{{{2}}}|категории|categories|{{{2}}}}}}}}}"}} | depth = {{#if:{{{3}}}|{{{3}}}}} }} </div><noinclude> {{doc}} </noinclude> 9763d532ff7b79a638abe485875db984254b57db Шаблон:Заглавная/Шапка 10 6 13 2024-05-18T12:48:35Z ruwiki>Putnik 0 некрасиво разбивается на строки в новом Векторе wikitext text/x-wiki <noinclude><templatestyles src="Шаблон:Заглавная/styles.css" /></noinclude> <templatestyles src="Шаблон:Заглавная/Шапка/styles.css" /> <div class="main-block main-top"> <div class="main-top-left"> <h1 class="main-top-header">Добро пожаловать в&nbsp;[[Википедия|Википедию]],</h1> [[Свободный контент|свободную энциклопедию]], которую [[Справка:Введение в Википедию|может редактировать каждый]]. <div class="main-top-mobileSearch"><span class="main-top-mobileSearchButton skin-minerva-search-trigger">[[Special:Search|Искать среди {{NUMBEROFARTICLES}} {{plural:{{NUMBEROFARTICLES}}|статьи|статей}}]]</span></div> </div> <div class="main-top-right main-plainlist"> <p class="main-top-articleCount">Сейчас в&nbsp;Википедии '''[[Special:Statistics|{{NUMBEROFARTICLES}} {{plural:{{NUMBEROFARTICLES}}|статья|статьи|статей}}]]''' на&nbsp;[[Русский язык|русском&nbsp;языке]].</p> <ul> <li class="main-top-createArticle">{{Заглавная/Кнопка|Википедия:Мастер статей|Создать статью}}</li> <li>{{Заглавная/Кнопка|Википедия:Справка|Справка|class=mw-ui-quiet}}</li> <li>{{Заглавная/Кнопка|Портал:Обзор|Порталы|class=mw-ui-quiet}}</li> </ul> </div> </div><noinclude> [[Категория:Шаблоны:Подстраницы шаблонов|Заглавная]] [[Категория:Шаблоны, используемые на Заглавной странице]] </noinclude> 824063451cf8a6bfd68477221e98b721c54adfe9 Модуль:Message box/ambox.css 828 209 466 2024-05-18T12:53:45Z ruwiki>Putnik 0 цвета я всё-таки верну sanitized-css text/css /* Скопировано из [[:en:Module:Message box/ambox.css]] с изменениями */ .ambox { border: 1px solid var(--border-color-base, #a2a9b1); /* @noflip */ border-left: 10px solid #36c; /* Default "notice" blue */ background: var(--background-color-neutral-subtle, #f8f9fa); box-sizing: border-box; margin: 0 10%; } /* Не ухудшаем стили для Минервы */ html body.mediawiki.skin-minerva .ambox { border-width: 0 0 0 4px; } /* Single border between stacked boxes. Take into account base templatestyles, * user styles, and Template:Dated maintenance category. * remove link selector when T200206 is fixed */ .ambox + link + .ambox, .ambox + link + style + .ambox, .ambox + link + link + .ambox, /* TODO: raise these as "is this really that necessary???". the change was Dec 2021 */ .ambox + .mw-empty-elt + link + .ambox, .ambox + .mw-empty-elt + link + style + .ambox, .ambox + .mw-empty-elt + link + link + .ambox { margin-top: -1px; } /* For the "small=left" option. */ /* must override .ambox + .ambox styles above */ html body.mediawiki .ambox.mbox-small-left { /* @noflip */ margin: 4px 1em 4px 0; overflow: hidden; width: 238px; border-collapse: collapse; font-size: 88%; line-height: 1.25em; } .ambox-speedy { /* @noflip */ border-left: 10px solid var(--border-color-error, #b32424); /* Red */ background-color: var(--background-color-error-subtle, #fee7e6); /* Pink */ } .ambox-delete { /* @noflip */ border-left: 10px solid var(--border-color-error, #b32424); /* Red */ } .ambox-content { /* @noflip */ border-left: 10px solid #f28500; /* Orange */ } .ambox-style { /* @noflip */ border-left: 10px solid var(--color-warning, #edab00); /* Yellow */ } .ambox-good { /* @noflip */ border-left: 10px solid #66cc44; } .ambox-discussion { /* @noflip */ border-left: 10px solid #339966; } .ambox-merge { /* @noflip */ border-left: 10px solid #9932cc; } .ambox-move { /* @noflip */ border-left: 10px solid #9932cc; /* Purple */ } .ambox-protection { /* @noflip */ border-left: 10px solid #a2a9b1; /* Gray-gold */ } .ambox .mbox-text { border: none; /* @noflip */ padding: 0.25em 0.5em; width: 100%; } .ambox .mbox-image { border: none; /* @noflip */ padding: 2px 0 2px 0.5em; text-align: center; } .ambox .mbox-imageright { border: none; /* @noflip */ padding: 2px 0.5em 2px 0; text-align: center; } /* An empty narrow cell */ .ambox .mbox-empty-cell { border: none; padding: 0; width: 1px; } .ambox .mbox-image-div { width: 52px; } /* Хак, TODO: посмотреть, как оно на самом деле работает */ .ambox .mbox-textsmall-div { font-size: 90%; } /* Hack around MobileFrontend being opinionated */ html.client-js body.skin-minerva .mbox-text-span { margin-left: 23px !important; } /* Стили нотификаций для ноутбуков */ @media (max-width: 1366px) { .ambox { margin-left: 6%; margin-right: 6%; } } /* Стили нотификаций для мобильного устройсва */ @media (max-width: 719px) { .ambox { margin-left: 0; margin-right: 0; } } /* [[Категория:Модули:Подстраницы CSS]] */ 1d03f5efb7ec589bb5edde009c3ae9ef13460e7e Шаблон:Политик 10 259 679 2024-05-23T21:34:43Z ruwiki>Abiyoyo 0 в пользу сортировки по изображениям wikitext text/x-wiki {{Карточка |имя = Политик |from = {{{from|}}} |стиль_меток = min-width:9em; |вверху = {{карточка/имя|{{{имя|{{{Имя|}}}}}}|from={{{from|}}}}} |вверху2 = {{карточка/оригинал имени|{{{оригинал имени|{{{Оригинал имени|}}}}}}|from={{{from|}}}}} |изображение = {{wikidata|p18|{{{изображение|{{{Изображение|}}}}}}|size={{{ширина|{{{Ширина|}}}}}}|caption={{{описание изображения|{{{Описание изображения|}}}}}}|from={{{from|}}}}} |метка1 = Имя при рождении |текст1 = {{{имя при рождении|{{{Имя при рождении|}}}}}} |метка2 = Псевдонимы |текст2 = {{{псевдонимы|{{{Псевдонимы|}}}}}} |метка3 = Дата&nbsp;рождения |текст3 = {{wikidata/p569|{{{дата рождения|{{{Дата рождения|}}}}}}|{{{дата смерти|{{{Дата смерти|}}}}}}|from={{{from|}}}}} |метка4 = Место рождения |текст4 = {{{место рождения|{{{Место рождения|}}}}}} |викиданные4 = p19 |метка5 = Дата&nbsp;смерти |текст5 = {{wikidata/p570|{{{дата смерти|{{{Дата смерти|}}}}}}|{{{дата рождения|{{{Дата рождения|}}}}}}|from={{{from|}}}}} |метка6 = Место смерти |текст6 = {{{место смерти|{{{Место смерти|}}}}}} |викиданные6 = p20 |метка7 = Гражданство |текст7 = {{{страна|{{{гражданство|{{{подданство|{{{Гражданство|}}}}}}}}}}}} |викиданные7 = p27 |метка8 = Род&nbsp;деятельности |текст8 = {{{род деятельности|{{{Род деятельности|}}}}}} |викиданные8 = p106 |метка9 = Образование |текст9 = {{{образование|{{{альма-матер|{{{Образование|}}}}}}}}} |викиданные9 = p69 |метка10 = Учёная степень |текст10 = {{{учёная степень|{{{Учёная степень|}}}}}} |викиданные10 = p512 |метка11 = Учёное звание |текст11 = {{{учёное звание|{{{Учёное звание|}}}}}} |метка12 = Вероисповедание |текст12 = {{{вероисповедание|{{{Вероисповедание|}}}}}} |викиданные12 = p140 |метка13 = Партия |текст13 = {{{партия|{{{Партия|}}}}}} |викиданные13 = p102 |метка14 = Основные идеи |текст14 = {{{основные идеи|{{{Основные идеи|}}}}}} |викиданные14 = p1142 |метка15 = Отец |текст15 = {{{отец|{{{Отец|}}}}}} |викиданные15 = p22 |метка16 = Мать |текст16 = {{{мать|{{{Мать|}}}}}} |викиданные16 = p25 |метка17 = {{wikidata gender switch||Супруг|Супруга|Супруг(а)}} |текст17 = {{wikidata|p26|{{#if: {{{супруга|{{{Супруга|}}}}}} | {{{супруга|{{{Супруга|}}}}}} | {{{супруг|{{{Супруг|}}}}}} }}}} |метка18 = Дети |текст18 = {{{дети|{{{Дети|}}}}}} |викиданные18 = p40 |метка19 = Награды |текст19 = {{{награды|{{{награды и премии|{{{Награды|}}}}}}}}} |викиданные19 = p166 |метка20 = Автограф |текст20 = {{wikidata|p109|{{{автограф|{{{Автограф|}}}}}}|size={{#if:{{{ширина автографа|{{{Ширина автографа|}}}}}}|{{{ширина автографа|{{{Ширина автографа}}}}}}|143x143}}|alt=Автограф|from={{{from|}}}}} |внизу = {{wikidata|p856|{{{сайт|{{{Сайт|}}}}}}|from={{{from|}}}}} |внизу2 = {{карточка/Викисклад|{{{викисклад|{{{Викисклад|}}}}}}|from={{{from|}}}}} }}<!-- -->{{#if:{{NAMESPACE}}{{{nocat|}}}||<!-- -->[[Категория:Персоналии по алфавиту]]<!-- -->[[Категория:Политики по алфавиту]]<!-- -->{{#invoke:Wikidata/category|categorizeIfNoParams}}<!-- -->{{#invoke:CategoryForProfession|mainFunction}}<!-- -->{{Сортировка: по изображениям|{{{изображение|{{{Изображение|}}}}}}|from={{{from|}}}|nocat={{{nocat|}}}|default-type=человек|default-occupation=политик}}<!-- -->}}<!-- -->{{#invoke:check for unknown parameters|check | unknown = {{#if: {{NAMESPACE}} || [[Категория:Страницы с неизвестными параметрами шаблона Политик|_VALUE_]] }} | ignoreblank = | preview = <span class="error">Неизвестный параметр «_VALUE_» шаблона Политик</span> | showblankpositional= 1 |from|nocat|Автограф|Вероисповедание|Викисклад|Гражданство|Дата рождения|Дата смерти|Дети|Изображение|Имя|Имя при рождении|Мать|Место рождения|Место смерти|Награды|Образование|Описание изображения|Оригинал имени|Основные идеи|Отец|Партия|Псевдонимы|Род деятельности|Сайт|Супруг|Супруга|Учёная степень|Учёное звание|Ширина|Ширина автографа<!-- -->|автограф|вероисповедание|викисклад|гражданство|дата рождения|дата смерти|дети|изображение|имя|имя при рождении|мать|место рождения|место смерти|награды|образование|описание изображения|оригинал имени|основные идеи|отец|партия|псевдонимы|род деятельности|сайт|супруг|супруга|учёная степень|учёное звание|ширина|ширина автографа |альма-матер|страна|подданство|награды и премии }}<!-- --><noinclude>{{doc}}</noinclude> 6e99fb4d8a3ec44096ba8d60276e31241c0d8f65 Модуль:Message box/fmbox.css 828 225 498 2024-06-03T18:54:56Z ruwiki>Putnik 0 поддержка тёмной темы sanitized-css text/css /* Скопировано из [[:en:Module:Message box/fmbox.css]] с изменениями */ .fmbox { clear: both; margin: 0.2em 0; width: 100%; border: 1px solid var(--border-color-base, #a2a9b1); background-color: var(--background-color-neutral-subtle, #f8f9fa); /* Default "system" gray */ box-sizing: border-box; } .fmbox-warning { border: 1px solid #bb7070; /* Dark pink */ background-color: #ffdbdb; /* Pink */ } .fmbox-editnotice { background-color: transparent; } .fmbox .mbox-text { border: none; /* @noflip */ padding: 0.25em 0.9em; width: 100%; } .fmbox .mbox-image { border: none; /* @noflip */ padding: 2px 0 2px 0.9em; text-align: center; } .fmbox .mbox-imageright { border: none; /* @noflip */ padding: 2px 0.9em 2px 0; text-align: center; } .fmbox .mbox-invalid-type { text-align: center; } /* Хак, TODO: посмотреть, как оно на самом деле работает */ .fmbox .mbox-textsmall-div { font-size: 90%; } /* [[Категория:Модули:Подстраницы CSS]] */ 313e9f5515a4f12a2a44d6c8d57f74cbda4bb464 Модуль:Wikidata/date 828 280 721 2024-06-10T15:24:01Z ruwiki>Stjn 0 необъявленная глобальная переменная Scribunto text/plain --settings local nowLabel = 'наст.&nbsp;время' local moduleDates = require( "Module:Dates" ) local moduleWikidata = require( "Module:Wikidata" ) local dateCat = require("Module:Infocards/dateCat") -- FIXME: undeclared global variable, used 3 times local infoclass local function deepcopy(orig) local orig_type = type(orig) local copy if orig_type == 'table' then copy = {} for orig_key, orig_value in next, orig, nil do copy[deepcopy(orig_key)] = deepcopy(orig_value) end setmetatable(copy, deepcopy(getmetatable(orig))) else -- number, string, boolean, etc copy = orig end return copy end local function ageImpl ( bStructure, bPrecision, dStructure, dPrecision ) if ( not bStructure or not dStructure or bPrecision < 10 or dPrecision < 10 ) then return nil end local shift = 0 if ( bStructure.year < 0 and dStructure.year > 0 ) then shift = -1 end if ( bPrecision == 10 or dPrecision == 10 ) then if ( bStructure.month < dStructure.month ) then return dStructure.year - bStructure.year + shift end if ( bStructure.month == dStructure.month ) then return nil end if ( bStructure.month > dStructure.month ) then return dStructure.year - bStructure.year - 1 + shift end end if ( bStructure.month < dStructure.month ) then return dStructure.year - bStructure.year + shift end if ( bStructure.month == dStructure.month ) then if ( bStructure.day <= dStructure.day ) then return dStructure.year - bStructure.year + shift else return dStructure.year - bStructure.year - 1 + shift end end if ( bStructure.month > dStructure.month ) then return dStructure.year - bStructure.year - 1 + shift end return nil end -- accepts table of time+precision values local function ageCurrent ( bTable ) local possibleAge = "NYA" -- it means "Not Yet Assigned", not what you imagined! for bKey, bValue in pairs(bTable) do if ( bValue.unknown ) then return nil end local bStructure = bValue.structure local bPrecision = bValue.precision local dStructure = os.date( "*t" ) local calculatedAge = ageImpl ( bStructure, bPrecision, dStructure, 11 ) if ( possibleAge == "NYA" ) then possibleAge = calculatedAge else if ( possibleAge ~= calculatedAge ) then possibleAge = nil end end end return possibleAge end -- accepts tables of time+precision values local function age ( bTable, dTable ) local possibleAge = "NYA" -- it means "Not Yet Assigned", not what you imagined! for bKey, bValue in pairs( bTable ) do if ( bValue.unknown ) then return nil end local bStructure = bValue.structure local bPrecision = bValue.precision for dKey, dValue in pairs( dTable ) do if ( dValue.unknown ) then return nil end local dStructure = dValue.structure local dPrecision = dValue.precision if ( bValue.calendar == 'julian' and dValue.calendar == 'gregorian' ) then -- to calculate age, need to adjust bStructure to gregorian calendar local shift = math.floor(bStructure.year/100-2) - math.floor(bStructure.year/400) -- TODO: re-implement this properly bStructure.day = bStructure.day + shift end local calculatedAge = ageImpl ( bStructure, bPrecision, dStructure, dPrecision ) if ( possibleAge == "NYA" ) then possibleAge = calculatedAge else if ( possibleAge ~= calculatedAge ) then possibleAge = nil end end end end return possibleAge end local function parseISO8601Date(str) local pattern = "(%-?%d+)%-(%d+)%-(%d+)T" local Y, M, D = mw.ustring.match( str, pattern ) return tonumber(Y), tonumber(M), tonumber(D) end local function parseISO8601Time(str) local pattern = "T(%d+):(%d+):(%d+)%Z" local H, M, S = mw.ustring.match( str, pattern) return tonumber(H), tonumber(M), tonumber(S) end local function parseISO8601Offset(str) if str:sub(-1)=="Z" then return 0,0 end -- ends with Z, Zulu time -- matches ±hh:mm, ±hhmm or ±hh; else returns nils local pattern = "([-+])(%d%d):?(%d?%d?)$" local sign, oh, om = mw.ustring.match( str, pattern) sign, oh, om = sign or "+", oh or "00", om or "00" return tonumber(sign .. oh), tonumber(sign .. om) end local function parseISO8601(str) if 'table' == type(str) then if str.args and str.args[1] then str = '' .. str.args[1] else return 'unknown argument type: ' .. type( str ) .. ': ' .. table.tostring( str ) end end local Y,M,D = parseISO8601Date(str) local h,m,s = parseISO8601Time(str) local oh,om = parseISO8601Offset(str) if not Y or not M or not D or not h or not m or not s or not oh or not om then return nil end return tonumber(os.time({year=Y, month=M, day=D, hour=(h+oh), min=(m+om), sec=s})) end local function parseClaim ( claim ) if ( claim.mainsnak.snaktype == "value" ) then local timeISO8601 = string.gsub( string.gsub( tostring( claim.mainsnak.datavalue.value.time ), '-00%-', '-01-' ), '-00T', '-01T' ) local unixtime = parseISO8601( timeISO8601 ) local structure = os.date("*t", unixtime) local precision = tonumber( claim.mainsnak.datavalue.value.precision ) local calendarmodel = 'gregorian' if (mw.ustring.find(claim.mainsnak.datavalue.value.calendarmodel, 'Q1985786', 1, true)) then calendarmodel = 'julian' end local item = { structure=structure, precision=precision, calendar = calendarmodel } return item elseif ( claim.mainsnak.snaktype == "novalue" ) then -- novalue return { unknown="novalue" } else --unknown return { unknown="unknown" } end end -- returns table of time+precision values for specified property local function parseProperty ( context, options, propertyId ) if ( not context ) then error( 'context not specified'); end if ( not options ) then error( 'options not specified'); end if ( not options.entity ) then error( 'options.entity is missing'); end if ( not propertyId ) then error( 'propertyId not specified'); end local claims = context.selectClaims( options, propertyId ) if not claims then return nil end local result = {} for key, claim in pairs( claims ) do table.insert ( result, parseClaim( claim ) ) end return result end -- проверка на совпадающие даты с разной моделью календаря local function checkDupDates( t ) if #t > 1 then local removed = false local j = 1 -- проверка на совпадающие даты с разной моделью календаря while (j <= #t) do local i = 1 while (i <= #t) do if i ~= j then if (os.time(t[j].structure) == os.time(t[i].structure)) then if ((t[j].calendarmodel == 'gregorian') and (t[i].calendarmodel == 'julian')) then removed = true break else table.remove(t, i) end else i = i + 1 end else i = i + 1 end end if removed then removed = false table.remove(t, j) else j = j+1 end end end end -- returns first qualifier of specified propertyId local function getQualifierWithDataValue( statement, qualifierPropertyId ) if ( statement.qualifiers and statement.qualifiers[qualifierPropertyId] ) then local qualifiers = statement.qualifiers[qualifierPropertyId] for _, qualifier in ipairs( qualifiers ) do if (qualifier.datavalue) then return qualifier end end end return nil end local p = {} local function formatDecade( time, categoryNamePrefix ) local bce = '' local year if time.year < 0 then bce = ' до н. э.' year = math.floor( math.abs( time.year ) / 10 ) * 10 else year = math.floor( time.year / 10 ) * 10 end local unit = '-е' if isGenitive then unit = '-х' end local value = '' .. year .. unit .. bce if categoryNamePrefix then return value .. '[[Category:' .. categoryNamePrefix .. ' в ' .. year .. '-е годы' .. bce .. ']]' end return value end local function formatCentury( time, categoryNamePrefix, isGenitive ) local moduleRoman = require( 'Module:RomanNumber' ) local bce = '' local century if time.year < 0 then bce = ' до н. э.' century = math.floor( ( math.abs( time.year ) - 1 ) / 100 ) + 1 else century = math.floor( ( time.year - 1 ) / 100 ) + 1 end local unit = 'век' if isGenitive then unit = 'века' end local infix = ' в ' if century == 2 then infix = ' во ' end if moduleRoman then century = moduleRoman.toRomanNumber( century ) end local value = '[[' .. century .. ' век' .. bce .. '|' .. century .. ' ' .. unit .. bce .. ']]' if categoryNamePrefix then return value .. '[[Category:' .. categoryNamePrefix .. infix .. century .. ' веке' .. bce .. ']]' end return value end local function formatMillenium( time, categoryNamePrefix, isGenitive ) local bce = '' local millenium if time.year < 0 then bce = ' до н. э.' millenium = math.floor( ( math.abs( time.year ) - 1 ) / 1000 ) + 1 else millenium = math.floor( ( time.year - 1 ) / 1000 ) + 1 end local unit = '-е тысячелетие' if isGenitive then unit = '-го тысячелетия' end local value = '[[' .. millenium .. '-е тысячелетие' .. bce .. '|' .. millenium .. unit .. bce .. ']]' if categoryNamePrefix then local infix = ' в ' if millenium == 2 then infix = ' во ' end return value .. '[[Category:' .. categoryNamePrefix .. infix .. millenium .. '-м тысячелетии' .. bce .. ']]' else return value end end local function formatDateImpl( value, options, microformatClass, categoryPrefix, leftBracket, rightBracket, nolinks, isGenitive ) if ( not value ) then error( 'value not specified'); end if ( not options ) then error( 'options not specified'); end -- The calendar model used for saving the data is always the proleptic Gregorian calendar according to ISO 8601. local timeISO8601 = string.gsub( string.gsub( tostring( value.time ), '-00%-', '-01-' ), '-00T', '-01T' ) local unixtime = parseISO8601( timeISO8601 ) if not unixtime then return '' end local structure = os.date("*t", unixtime) local precision = tonumber( value.precision ) if precision <= 6 then return formatMillenium( structure, categoryPrefix, isGenitive ) end if precision == 7 then return formatCentury( structure, categoryPrefix, isGenitive ) end if precision == 8 then return formatDecade( structure, categoryPrefix, isGenitive ) end if precision == 9 then local tCopy = deepcopy( structure ) tCopy.day = nil tCopy.month = nil return moduleDates.formatWikiImpl( tCopy, tCopy, infoclass, categoryPrefix, leftBracket, rightBracket, nolinks ) end -- year and month only if precision == 10 then local tCopy = deepcopy( structure ) tCopy.day = nil return moduleDates.formatWikiImpl( tCopy, tCopy, infoclass, categoryPrefix, leftBracket, rightBracket, nolinks ) end local calendarmodel = 'gregorian' if (mw.ustring.find(value.calendarmodel, 'Q1985786', 1, true)) then calendarmodel = 'julian' end if (calendarmodel == 'gregorian') then return moduleDates.formatWikiImpl( structure, structure, microformatClass, categoryPrefix, leftBracket, rightBracket, nolinks ) else return p.formatAsJulian( timeISO8601, infoclass, categoryPrefix, leftBracket, rightBracket, nolinks ) end end local function formatApproximateDateClaim( context, options, statement, unknownDateCategory ) if ( not context ) then error( 'context not specified'); end if ( not options ) then error( 'options not specified'); end if ( not options.entity ) then error( 'options.entity is missing'); end if ( not statement ) then error( 'statement not specified'); end if options.nocat then unknownDateCategory = "" end local qNotSoonerThan = getQualifierWithDataValue( statement, 'P1319' ) local qNotLaterThan = getQualifierWithDataValue( statement, 'P1326' ) if ( qNotSoonerThan or qNotLaterThan ) then local results = {} if ( qNotSoonerThan ) then local formattedDate = formatDateImpl( qNotSoonerThan.datavalue.value, {}, nil, nil, options.leftBracket, options.rightBracket, options.nolinks, true ) local value = 'не&nbsp;ранее&nbsp;' .. context.wrapSnak( formattedDate, qNotSoonerThan.hash ) table.insert( results, context.wrapQualifier( value, 'P1319' ) ) end if ( qNotLaterThan ) then local formattedDate = formatDateImpl( qNotLaterThan.datavalue.value, {}, nil, nil, options.leftBracket, options.rightBracket, options.nolinks, true ) local value = 'не&nbsp;позднее&nbsp;' .. context.wrapSnak( formattedDate, qNotLaterThan.hash ) table.insert( results, context.wrapQualifier( value, 'P1326' ) ) end return mw.text.listToText( results, ' и ' , ' и ' ) .. unknownDateCategory .. context.formatRefs( options, statement ) end return nil end function p.formatDateOfBirthClaim( context, options, statement ) local value = formatApproximateDateClaim( context, options, statement, dateCat.categoryUnknownBirthDate ) if value then return value end options['conjunction'] = '&#32;или&#32;' options['value-module'] = 'Wikidata/date' options['value-function'] = 'formatBirthDate' options.i18n.somevalue = '\'\'неизвестно\'\'' .. dateCat.categoryUnknownBirthDate local circumstances = context.getSourcingCircumstances( statement ) for _, itemId in ipairs( circumstances ) do if itemId == 'Q5727902' then options.isGenitive = true break end end local result = context.formatStatementDefault( context, options, statement ) local bTable = { parseClaim( statement ) } local dTable = parseProperty ( context, options, 'P570' ) if ( bTable and not dTable ) then local age = ageCurrent( bTable ) if ( age ) then if ( options.suppressAge == nil or options.suppressAge == '' ) then result = result .. ' <span style="white-space:nowrap;">(' .. age .. ' ' .. mw.language.new( 'ru' ):plural( age, 'год', 'года', 'лет') .. ')</span>' end if ( not options.nocat ) then if ( age > 115 ) then result = result .. dateCat.categoryBigCurrentAge elseif (age >= 0) then result = result .. dateCat.categoryBiographiesOfLivingPersons else result = result .. dateCat.categoryNegativeAge end end end end return result end function p.formatDateOfDeathClaim( context, options, statement ) local value = formatApproximateDateClaim( context, options, statement, dateCat.categoryUnknownDeathDate ) if value then return value end options['conjunction'] = '&#32;или&#32;' options['value-module'] = 'Wikidata/date' options['value-function'] = 'formatDeathDate' options.i18n.somevalue = '\'\'неизвестно\'\'' .. dateCat.categoryUnknownDeathDate local circumstances = context.getSourcingCircumstances( statement ) for _, itemId in ipairs( circumstances ) do if itemId == 'Q5727902' then options.isGenitive = true break end end local result = context.formatStatementDefault( context, options, statement ) local bTable = parseProperty ( context, options, 'P569' ) local dTable = { parseClaim( statement ) } if ( bTable and dTable ) then local age = age( bTable, dTable ) if ( age ) then if ( options.suppressAge == nil or options.suppressAge == '' ) then result = result .. ' <span style="white-space:nowrap;">(' .. age .. ' ' .. mw.language.new( 'ru' ):plural( age, 'год', 'года', 'лет') .. ')</span>' end if ( not options.nocat and age < 0) then result = result .. dateCat.categoryNegativeAge end end -- returns category to recently deceased persons local unixAvailable, unixDateOfDeath = pcall(function() local r = os.time(dTable[1].structure) if ( r ~= os.time() ) then return r end error() end) if ( unixAvailable and os.time() - unixDateOfDeath < 31536000 and not options.nocat ) then result = result .. dateCat.categoryRecentlyDeceased end end return result end -- Reentry point for Wikidata Snak formatting function p.formatBirthDate( context, options, value ) if ( not context ) then error( 'context not specified'); end if ( not options ) then error( 'options not specified'); end if ( not value ) then error( 'value not specified'); end local microformatClass = nil if options.microformat ~= '-' then microformatClass = options.microformat or 'bday' end if ( options.nocat ) then return formatDateImpl( value, options, microformatClass, nil, options.leftBracket, options.rightBracket, options.nolinks, options.isGenitive ) else return formatDateImpl( value, options, microformatClass, 'Родившиеся', options.leftBracket, options.rightBracket, options.nolinks, options.isGenitive ) end end -- Reentry point for Wikidata Snak formatting function p.formatDeathDate( context, options, value ) if ( not context ) then error( 'context not specified'); end if ( not options ) then error( 'options not specified'); end if ( not value ) then error( 'value not specified'); end local microformatClass = nil if options.microformat ~= '-' then microformatClass = options.microformat or 'dday' end if ( options.nocat and options.nocat ~= '' ) then return formatDateImpl( value, options, microformatClass, nil, options.leftBracket, options.rightBracket, options.nolinks, options.isGenitive ) else return formatDateImpl( value, options, microformatClass, 'Умершие', options.leftBracket, options.rightBracket, options.nolinks, options.isGenitive ) end end -- Reentry point for Wikidata Snak formatting -- default one function p.formatDate( context, options, value ) if ( not context ) then error( 'context not specified'); end if ( not options ) then error( 'options not specified'); end if ( not value ) then error( 'value not specified'); end local microformatClass = options.microformat or nil if ( options.nocat and options.nocat ~= '' ) then return formatDateImpl( value, options, microformatClass, nil, options.leftBracket, options.rightBracket, options.nolinks, options.isGenitive ) else local categoryPrefix = options.categoryPrefix or nil return formatDateImpl( value, options, microformatClass, categoryPrefix, options.leftBracket, options.rightBracket, options.nolinks, options.isGenitive ) end end function p.formatDateIntervalProperty( context, options ) if ( not context ) then error( 'context not specified' ); end if ( not options ) then error( 'options not specified' ); end if ( not options.entity ) then error( 'options.entity missing' ); end -- Получение нужных утверждений local WDS = require( 'Module:WikidataSelectors' ) local fromProperty = options.property if options.from and options.from ~= '' then fromProperty = options.from end local fromClaims = WDS.load( options.entityId, fromProperty ) local toClaims = WDS.load( options.entityId, options.to ) if fromClaims == nil and toClaims == nil then return '' end local formattedFromClaims = {} if fromClaims then for i, claim in ipairs( fromClaims ) do local formattedStatement = context.formatStatement( options, claim ) if formattedStatement then formattedStatement = '<span class="wikidata-claim" data-wikidata-property-id="' .. string.upper( options.property ) .. '" data-wikidata-claim-id="' .. claim.id .. '">' .. formattedStatement .. '</span>' table.insert( formattedFromClaims, formattedStatement ) end end end local formattedToClaims = {} local toOptions = deepcopy( options ) toOptions.property = options.to toOptions.novalue = nowLabel if toClaims then for i, claim in ipairs( toClaims ) do local formattedStatement = context.formatStatement( toOptions, claim ) if formattedStatement then formattedStatement = '<span class="wikidata-claim" data-wikidata-property-id="' .. string.upper( toOptions.property ) .. '" data-wikidata-claim-id="' .. claim.id .. '">' .. formattedStatement .. '</span>' table.insert( formattedToClaims, formattedStatement ) end end end local out = '' local fromOut = mw.text.listToText( formattedFromClaims, options.separator, options.conjunction ) local toOut = mw.text.listToText( formattedToClaims, options.separator, options.conjunction ) if fromOut ~= '' or toOut ~= '' then if fromOut ~= '' then out = fromOut else out = '?' end if toOut ~= '' then out = out .. ' — ' .. toOut else local withinClaims = nil if options.within then WDS.load( options.entityId, options.within ) end if withinClaims == nil then out = 'с ' .. out else out = out .. ' — ' .. nowLabel end end end if out ~= '' then if options.before then out = options.before .. out end if options.after then out = out .. options.after end end return out end local lowestBoundary = '1582-10-05T00:00:00Z' local lastBoundary = '1918-01-31T00:00:00Z' local boundaries = { -- from (G) till next will be diff(G = J + diff), at current { lowestBoundary, 10 }, { '1700-02-29T00:00:00Z', 11 }, { '1800-02-29T00:00:00Z', 12 }, { '1900-02-29T00:00:00Z', 13 }, { lastBoundary, '' }, } -- Передаваемое время обязано быть по Юлианскому календарю (старому стилю) function p.formatAsJulian( julTimeISO8601, infocardClass, categoryNamePrefix, leftBracket, rightBracket, nolinks ) if 'table' == type( julTimeISO8601 ) then if julTimeISO8601.args and julTimeISO8601.args[1] then julTimeISO8601 = julTimeISO8601.args[1] else return 'unknown argument type: ' .. type( julTime ) .. ': ' .. table.tostring( julTime ) end end julTimeISO8601 = mw.text.trim( julTimeISO8601 ) julTimeISO8601 = string.gsub( julTimeISO8601, '^+', '' ) local julTime = parseISO8601( julTimeISO8601 ) local t = os.date( "*t", julTime ) if ( julTime < parseISO8601( lowestBoundary ) ) then -- only julian if string.find( julTimeISO8601, '-02-29T', 1, true ) then t = { year = t.year, month = 2, day = 29 } end return moduleDates.formatWikiImpl( t, t, infocardClass, categoryNamePrefix, leftBracket, rightBracket, nolinks ) end if ( julTimeISO8601 >= lastBoundary ) then return "''некорректная дата (юлианский календарь не используется после 1918-01-26)''" end -- julian and grigorian for i = 1, #boundaries, 1 do local b1 = boundaries[i][1] local b2 = boundaries[i + 1][1] if ( b1 <= julTimeISO8601 and julTimeISO8601 < b2 ) then local diff = boundaries[i][2] if string.sub( julTimeISO8601, 1, 10 ) == string.sub( boundaries[i][1], 1, 10 ) then t = { year = t.year, month = 2, day = 29 } diff = diff - 1 end local gregTime = os.date( "*t", julTime + diff * 24 * 60 * 60 ) return moduleDates.formatWikiImpl( t, gregTime, infocardClass, categoryNamePrefix, leftBracket, rightBracket, nolinks ) end end return "''ошибка в модуле Модуль:Wikidata/date''" end return p 12c2c34efd103d2938bd65421aa550e8c6f26da0 Модуль:Sources 828 140 322 2024-06-10T20:41:59Z ruwiki>Stjn 0 возврат, сломало [[Википедия:Форум/Технический#Ошибка lua]] Scribunto text/plain ---@alias args table ---@alias frame { args: args, extensionTag: function, newChild: ( fun( args: args ): frame ) } ---@alias source { publication: source, [string]: any } ---@alias value: string | { id: string } ---@alias snak { datatype: string, snaktype: string, datavalue: { type: string, value: value } } ---@alias snaks table<string, table<number, snak>> ---@alias statement { mainsnak: snak, rank: string, qualifiers: snaks } ---@alias statements table<string, table<number, statement>> ---@alias map { name: string, ids: string[] }[]> ---@type table local p = {} ---@type table<string, string> local NORMATIVE_DOCUMENTS = { Q20754888 = 'Закон Российской Федерации', Q20754884 = 'Закон РСФСР', Q20873831 = 'Распоряжение Президента Российской Федерации', Q20873834 = 'Указ исполняющего обязанности Президента Российской Федерации', Q2061228 = 'Указ Президента Российской Федерации', } ---@type table<string, string> local LANG_CACHE = { Q150 = 'fr', Q188 = 'de', Q1321 = 'es', Q1860 = 'en', Q652 = 'it', Q7737 = 'ru', Q8798 = 'uk', } ---@type map local PROPERTY_MAP = { { name = 'sourceId', ids = { 'P248', 'P805' } }, { name = 'lang', ids = { 'P407', 'P364' } }, { name = 'author', ids = { 'P50', 'P2093' } }, { name = 'part', ids = { 'P958', 'P1810' } }, { name = 'title', ids = { 'P1476' } }, { name = 'subtitle', ids = { 'P1680' } }, { name = 'url', ids = { 'P953', 'P1065', 'P854', 'P973', 'P2699', 'P888' } }, { name = 'editor', ids = { 'P98' } }, { name = 'translator', ids = { 'P655' } }, { name = 'publication-id', ids = { 'P1433' } }, { name = 'edition', ids = { 'P393' } }, { name = 'publisher', ids = { 'P123' } }, { name = 'place', ids = { 'P291' } }, { name = 'volume', ids = { 'P478' } }, { name = 'issue', ids = { 'P433' } }, { name = 'dateOfCreation', ids = { 'P571' } }, { name = 'dateOfPublication', ids = { 'P577' } }, { name = 'pages', ids = { 'P304' } }, { name = 'numberOfPages', ids = { 'P1104' } }, { name = 'tirage', ids = { 'P1092' } }, { name = 'isbn', ids = { 'P212', 'P957' } }, { name = 'issn', ids = { 'P236' } }, -- { name = 'accessdate', ids = { 'P813' } }, -- disable, creates duplicate references { name = 'docNumber', ids = { 'P1545' } }, { name = 'type', ids = { 'P31' } }, { name = 'arxiv', ids = { 'P818' } }, { name = 'doi', ids = { 'P356' } }, { name = 'pmid', ids = { 'P698' } }, } -- table.insert( PROPERTY_MAP.url, 'P856' ) -- only as qualifier ---@type map local PUBLICATION_PROPERTY_MAP = mw.clone( PROPERTY_MAP ) ---@type string[] local monthGen = { 'января', 'февраля', 'марта', 'апреля', 'мая', 'июня', 'июля', 'августа', 'сентября', 'октября', 'ноября', 'декабря' } ---@type string local i18nDefaultLanguage = mw.language.getContentLanguage():getCode() p.i18nDefaultLanguage = i18nDefaultLanguage ---@type string local i18nEtAlDefault = ' et al.' ---@type table<string, string> local i18nEtAl = { ru = ' и др.', uk = ' та ін.', } ---@type table<string, string> local i18nEditors = { fr = '', de = 'Hrsg.: ', es = '', en = '', it = '', ru = 'под ред. ', uk = 'за ред. ', } ---@type table<string, string> local i18nTranslators = { fr = '', de = '', es = '', en = '', it = '', ru = 'пер. ', uk = 'пер. ', } ---@type table<string, string> local i18nVolume = { de = 'Vol.', fr = 'Vol.', es = 'Vol.', en = 'Vol.', it = 'Vol.', ru = 'Т.', uk = 'Т.', } ---@type table<string, string> local i18nIssue = { en = 'Iss.', ru = 'вып.', uk = 'вип.', } ---@type table<string, string> local i18nPages = { fr = 'P.', de = 'S.', es = 'P.', en = 'P.', it = 'P.', ru = 'С.', uk = 'С.', } ---@type table<string, string> local i18nNumberOfPages = { en = 'p.', ru = 'с.', } ---@type table<string, string> local i18nTirage = { en = 'ed. size: %d', ru = '%d экз.', } ---@param args args ---@return source local function getFilledArgs( args ) ---@type source local data = {} for key, value in pairs( args ) do if mw.text.trim( value ) ~= '' then if key == 1 then key = 'sourceId' end data[ key ] = mw.text.trim( value ) end end return data end ---Returns formatted pair {Family name(s), First name(s)} ---@param fullName string ---@return table<number, string> local function tokenizeName( fullName ) local space = '%s+' -- matches single or more spacing character local name = "(%a[%a%-']*)%.?" -- matches single name, have to start with letter, can contain apostrophe and hyphen, may end with dot local surname = "(%a[%a%-']*)" -- same as name, but can't end with dot local surnamePrefixes = { 'ван', 'van', 'де', 'de' } local nm, nm2, srn, srn2, pref fullName = ' ' .. fullName .. ' ' fullName = mw.ustring.gsub( fullName, ' оглы ', ' ' ) fullName = mw.text.trim( fullName ) -- Surname, Name local pattern = '^' .. surname .. ',' .. space .. name .. '$' srn, nm = mw.ustring.match( fullName, pattern ) if srn then return { srn, mw.ustring.sub( nm, 1, 1 ) .. '.' } end -- Surname, Name prefix for _, surnamePrefix in pairs( surnamePrefixes ) do pattern = '^' .. surname .. ',' .. space .. name .. space .. '(' .. surnamePrefix .. ')' .. '$' srn, nm, pref = mw.ustring.match( fullName, pattern ) if srn then return { mw.ustring.sub( pref ) .. ' ' .. srn, mw.ustring.sub( nm, 1, 1 ) .. '.' } end end -- Surname, Name Name pattern = '^' .. surname .. ',' .. space .. name .. space .. name .. '$' srn, nm, nm2 = mw.ustring.match( fullName, pattern ) if srn then return { srn, mw.ustring.sub( nm, 1, 1 ) .. '.&nbsp;' .. mw.ustring.sub( nm2, 1, 1 ) .. '.' } end -- Surname Surname, Name pattern = '^' .. surname .. space .. surname .. ',' .. space .. name .. '$' srn, srn2, nm = mw.ustring.match( fullName, pattern ) if srn then return { srn .. '&nbsp;' .. srn2, mw.ustring.sub( nm, 1, 1 ) .. '.' } end -- Name Name Surname pattern = '^' .. name .. space .. name .. space .. surname .. '$' nm, nm2, srn = mw.ustring.match( fullName, pattern ) if srn then return { srn, mw.ustring.sub( nm, 1, 1 ) .. '.&nbsp;' .. mw.ustring.sub( nm2, 1, 1 ) .. '.' } end -- Name Name prefix Surname for _, surnamePrefix in pairs( surnamePrefixes ) do pattern = '^' .. name .. space .. name .. space .. '(' .. surnamePrefix .. ')' .. space .. surname .. '$' nm, nm2, pref, srn = mw.ustring.match( fullName, pattern ) if srn then return { mw.ustring.sub( pref ) .. ' ' .. srn, mw.ustring.sub( nm, 1, 1 ) .. '.&nbsp;' .. mw.ustring.sub( nm2, 1, 1 ) .. '.' } end end -- Surname, Name Name prefix for _, surnamePrefix in pairs( surnamePrefixes ) do pattern = '^' .. surname .. ',' .. space .. name .. space .. name .. space .. '(' .. surnamePrefix .. ')' .. '$' srn, nm, nm2, pref = mw.ustring.match( fullName, pattern ) if srn then return { mw.ustring.sub( pref ) .. ' ' .. srn, mw.ustring.sub( nm, 1, 1 ) .. '.&nbsp;' .. mw.ustring.sub( nm2, 1, 1 ) .. '.' } end end -- Name{1,4} Surname for k = 1, 4 do pattern = '^' .. string.rep( name .. space, k ) .. surname .. '$' ---@type string[] local matched = { mw.ustring.match( fullName, pattern ) } if #matched ~= 0 then for j = 1, k do matched[ j ] = mw.ustring.sub( matched[ j ], 1, 1 ) end return { matched[ k + 1 ], table.concat( matched, '.&nbsp;', 1, k ) .. '.' } end end -- Surname Name{1,4} for k = 1, 4 do pattern = '^' .. surname .. string.rep( space .. name, k ) .. '$' ---@type string[] local matched = { mw.ustring.match( fullName, pattern ) } if #matched ~= 0 then for j = 2, k + 1 do matched[ j ] = mw.ustring.sub( matched[ j ], 1, 1 ) end return { matched[ 1 ], table.concat( matched, '.&nbsp;', 2, k + 1 ) .. '.' } end end return { fullName } end ---@param fullName string | nil ---@return string | nil local function personNameToAuthorName( fullName ) if not fullName then return nil end local tokenized = tokenizeName( fullName ) if #tokenized == 1 then return tokenized[ 1 ] end return tokenized[ 1 ] .. '&nbsp;' .. tokenized[ 2 ] end ---@param fullName string | nil ---@return string | nil local function personNameToResponsibleName( fullName ) if not fullName then return nil end local tokenized = tokenizeName( fullName ) if #tokenized == 1 then return tokenized[ 1 ] end return tokenized[ 2 ] .. '&nbsp;' .. tokenized[ 1 ] end ---@alias options { separator: string, conjunction: string, format: ( fun( data: string ): string ), nolinks: boolean, preferids: boolean, short: boolean } ---@type options local options_commas = { separator = ', ', conjunction = ', ', format = function( data ) return data end, nolinks = false, preferids = false, short = false, } ---@type options local options_commas_short = mw.clone( options_commas ) options_commas_short.short = true ---@type options local options_commas_it_short = mw.clone( options_commas_short ) options_commas_it_short.format = function( data ) return "''" .. data .. "''" end ---@type options local options_commas_nolinks = mw.clone( options_commas ) options_commas_nolinks.nolinks = true ---@type options local options_citetypes = { separator = ' ', conjunction = ' ', format = function( data ) return 'citetype_' .. data end, nolinks = true , preferids = true, short = false, } ---@type options local options_commas_authors = mw.clone( options_commas ) options_commas_authors.format = personNameToAuthorName ---@type options local options_commas_responsible = mw.clone( options_commas ) options_commas_responsible.format = personNameToResponsibleName ---@type options local options_ids = { separator = '; ', conjunction = '; ', format = function( id ) return id end, nolinks = true, preferids = false, short = false, } ---@type options local options_arxiv = mw.clone( options_ids ) options_arxiv.format = function( id ) return '[https://arxiv.org/abs/' .. id .. ' arXiv:' .. id .. ']' end ---@type options local options_doi = mw.clone( options_ids ) options_doi.format = function( doi ) return '[https://dx.doi.org/' .. doi .. ' doi:' .. doi .. ']' end ---@type options local options_issn = mw.clone( options_ids ) options_issn.format = function( issn ) return '[https://www.worldcat.org/issn/' .. issn .. ' ' .. issn .. ']' end ---@type options local options_pmid = mw.clone( options_ids ) options_pmid.format = function( pmid ) return '[https://www.ncbi.nlm.nih.gov/pubmed/?term=' .. pmid .. ' PMID:' .. pmid .. ']' end ---@param str string | nil ---@return boolean local function isEmpty( str ) return not str or #str == 0 end ---@param allQualifiers snaks ---@param qualifierPropertyId string ---@return string | nil local function getSingleStringQualifierValue( allQualifiers, qualifierPropertyId ) if not allQualifiers or not allQualifiers[ qualifierPropertyId ] then return nil end ---@type table<number, snak> local propertyQualifiers = allQualifiers[ qualifierPropertyId ] for _, qualifier in pairs( propertyQualifiers ) do if ( qualifier and qualifier.datatype == 'string' and qualifier.datavalue and qualifier.datavalue.type == 'string' and qualifier.datavalue.value ~= '' ) then return qualifier.datavalue.value end end return nil end ---@param data table ---@param resultProperty string ---@return void local function appendImpl_toTable( data, resultProperty ) if not data[ resultProperty ] then data[ resultProperty ] = {} elseif ( type( data[ resultProperty ] ) == 'string' or ( type( data[ resultProperty ] ) == 'table' and type( data[ resultProperty ].id ) == 'string' ) ) then data[ resultProperty ] = { data[ resultProperty ] } end end ---@param datavalue table ---@param qualifiers snaks ---@param data table ---@param propertyName string ---@param options table local function appendImpl( datavalue, qualifiers, data, propertyName, options ) data[ propertyName ] = data[ propertyName ] or {} if propertyName == 'issn' then table.insert( data[ propertyName ], datavalue.value ) elseif propertyName == 'url' or datavalue.type == 'url' then local value = datavalue.value if options.format then value = options.format( value ) end appendImpl_toTable( data, propertyName ) table.insert( data[ propertyName ], value ) elseif datavalue.type == 'string' then local value = getSingleStringQualifierValue( qualifiers, 'P1932' ) if not value then value = getSingleStringQualifierValue( qualifiers, 'P1810' ) end if not value then value = datavalue.value if options.format then value = options.format( value ) end end appendImpl_toTable(data, propertyName) local pos = getSingleStringQualifierValue( qualifiers, 'P1545' ) if pos then table.insert( data[ propertyName ], tonumber(pos), value ) else table.insert( data[ propertyName ], value ) end elseif datavalue.type == 'monolingualtext' then local value = datavalue.value.text if options.format then value = options.format( value ) end appendImpl_toTable( data, propertyName ) table.insert( data[ propertyName ], value ) elseif datavalue.type == 'quantity' then local value = datavalue.value.amount if ( mw.ustring.sub( value , 1, 1 ) == '+' ) then value = mw.ustring.sub( value , 2 ) end if options.format then value = options.format( value ) end appendImpl_toTable( data, propertyName ) table.insert( data[ propertyName ], value ) elseif datavalue.type == 'wikibase-entityid' then local pos = getSingleStringQualifierValue( qualifiers, 'P1545' ) local value = datavalue.value appendImpl_toTable(data, propertyName) local label = getSingleStringQualifierValue( qualifiers, 'P1932' ) if not label then label = getSingleStringQualifierValue( qualifiers, 'P1810' ) end local toInsert = { id = value.id, label = label } if pos and tonumber( pos ) then table.insert( data[ propertyName ], tonumber( pos ), toInsert ) else table.insert( data[ propertyName ], toInsert ) end elseif datavalue.type == 'time' then local value = datavalue.value if options.format then value = options.format( value ) end appendImpl_toTable( data, propertyName ) table.insert( data[ propertyName ], tostring( value.time ) ) end end ---@param entityId string ---@param propertyId string ---@return table<number, statement> local function getAllStatements( entityId, propertyId ) ---@type boolean, table<number, statement> local wdStatus, statements = pcall( mw.wikibase.getAllStatements, entityId, propertyId ) if wdStatus and statements then return statements end return {} end ---@param entityId string ---@param propertyId string ---@return table<number, statement> local function getBestStatements( entityId, propertyId ) ---@type boolean, table<number, statement> local wdStatus, statements = pcall( mw.wikibase.getBestStatements, entityId, propertyId ) if wdStatus and statements then return statements end return {} end ---@param entityId string ---@param projectToCheck string? ---@return string | nil local function getSitelink( entityId, projectToCheck ) ---@type boolean, string local wbStatus, sitelink if projectToCheck then wbStatus, sitelink = pcall( mw.wikibase.getSitelink, entityId, projectToCheck ) else wbStatus, sitelink = pcall( mw.wikibase.getSitelink, entityId ) end if not wbStatus then return nil end return sitelink end ---@param args any[] ---@return any | nil local function coalesce( args ) for _, arg in pairs( args ) do if not isEmpty( arg ) then return arg end end return nil end ---@param value any ---@return string | nil local function getSingle( value ) if type( value ) == 'string' then return tostring( value ) elseif type( value ) == 'table' then if value.id then return tostring( value.id ) end for _, tableValue in pairs( value ) do return getSingle( tableValue ) end end return nil end ---@param langEntityId string ---@return string | nil local function getLangCode( langEntityId ) if not langEntityId then return nil end langEntityId = getSingle( langEntityId ) if not string.match( langEntityId, '^Q%d+$' ) then return langEntityId end local cached = LANG_CACHE[ langEntityId ] if cached then if cached == '' then return nil end return cached end local claims = getBestStatements( langEntityId, 'P424' ) for _, claim in pairs( claims ) do if claim and claim.mainsnak and claim.mainsnak.datavalue and claim.mainsnak.datavalue.value then LANG_CACHE[ langEntityId ] = claim.mainsnak.datavalue.value return claim.mainsnak.datavalue.value end end LANG_CACHE[ langEntityId ] = '' return nil end ---@param entityId string ---@param propertyId string ---@param data source ---@param propertyName string ---@param options table? ---@return void local function appendEntitySnaks( entityId, propertyId, data, propertyName, options ) options = options or {} -- do not populate twice if data[ propertyName ] and ( propertyName ~= 'author' or data[ propertyId ] ) then return end local statements = getBestStatements( entityId, propertyId ) if propertyName == 'author' then data[ propertyId ] = true end local lang = getLangCode( data.lang ) or i18nDefaultLanguage if propertyId == 'P1680' then -- if there is a default language for _, statement in pairs( statements ) do if statement and statement.mainsnak and statement.mainsnak.datavalue and statement.mainsnak.datavalue.value and statement.mainsnak.datavalue.value.language == lang then --found default language string appendImpl( statement.mainsnak.datavalue, statement.qualifiers, data, propertyName, options ) return end end end for _, statement in pairs( statements ) do if statement and statement.mainsnak and statement.mainsnak.datavalue then appendImpl( statement.mainsnak.datavalue, statement.qualifiers or {}, data, propertyName, options ) if propertyName == 'publication-id' and statement.qualifiers then data[ 'publication-qualifiers' ] = statement.qualifiers end end end end ---@param claims table<number, statement> ---@param qualifierPropertyId string ---@param result table ---@param resultPropertyId string ---@param options table ---@return void local function appendQualifiers( claims, qualifierPropertyId, result, resultPropertyId, options ) -- do not populate twice if not claims or result[ resultPropertyId ] then return end for _, claim in pairs( claims ) do if claim.qualifiers and claim.qualifiers[ qualifierPropertyId ] then ---@type table<number, snak> local propertyQualifiers = claim.qualifiers[ qualifierPropertyId ] for _, qualifier in pairs( propertyQualifiers ) do if qualifier and qualifier.datavalue then appendImpl( qualifier.datavalue, nil, result, resultPropertyId, options ) end end end end end ---@param entityId string ---@param propertyId string ---@param value any ---@return table<number, statement> local function findClaimsByValue( entityId, propertyId, value ) local result = {} local claims = getAllStatements( entityId, propertyId ) for _, claim in pairs( claims ) do if ( claim.mainsnak and claim.mainsnak.datavalue ) then local datavalue = claim.mainsnak.datavalue if ( datavalue.type == "string" and datavalue.value == value ) or ( datavalue.type == "wikibase-entityid" and datavalue.value[ "entity-type" ] == "item" and tostring( datavalue.value.id ) == value ) then table.insert( result, claim ) end end end return result end ---@param entityId string ---@param typeEntityId string ---@return boolean local function isInstanceOf( entityId, typeEntityId ) return findClaimsByValue( entityId, 'P31', typeEntityId )[ 1 ] ~= nil end ---@param entityId string ---@param typeEntityIds string[] ---@return string ---@todo Rewrite local function getFirstType( entityId, typeEntityIds ) for _, typeEntityId in pairs( typeEntityIds ) do if isInstanceOf( entityId, typeEntityId ) then return typeEntityId end end return nil end ---@param snaks snaks ---@param data source ---@param map map ---@return void local function populateDataFromSnaks( snaks, data, map ) for _, row in ipairs( map ) do local parameterName, propertyIds = row.name, row.ids for _, propertyId in pairs( propertyIds ) do if not data[ parameterName ] and snaks[ propertyId ] then local options = {} if propertyId == 'P888' then options = { format = function( id ) return 'http://www.jstor.org/stable/' .. id end } end for _, snak in pairs( snaks[ propertyId ] ) do if snak and snak.datavalue then appendImpl( snak.datavalue, {}, data, parameterName, options ) end end end end end end ---@param entityId string | nil ---@param data source ---@param map map ---@return void local function populateDataFromEntity( entityId, data, map ) if not data.title then if not isEmpty( entityId ) then local optionsAsLinks = { format = function( text ) return { id = entityId, label = text } end } appendEntitySnaks( entityId, 'P1476', data, 'title', optionsAsLinks ) else appendEntitySnaks( entityId, 'P1476', data, 'title', {} ) end appendEntitySnaks( entityId, 'P1680', data, 'subtitle', {} ) end local bookSeriesStatements = getBestStatements( entityId, 'P361' ) for _, statement in pairs( bookSeriesStatements ) do if statement and statement.mainsnak and statement.mainsnak.datavalue and statement.mainsnak.datavalue.value and statement.mainsnak.datavalue.value.id then local possibleBookSeriesEntityId = statement.mainsnak.datavalue.value.id if isInstanceOf( possibleBookSeriesEntityId, 'Q277759' ) then appendImpl_toTable( data, 'bookSeries' ) table.insert( data.bookSeries, { id = possibleBookSeriesEntityId } ) appendQualifiers( { statement }, 'P478', data, 'bookSeriesVolume', {} ) appendQualifiers( { statement }, 'P433', data, 'bookSeriesIssue', {} ) end end end for _, row in ipairs( map ) do local parameterName, propertyIds = row.name, row.ids for _, propertyId in pairs( propertyIds ) do local options = {} if propertyId == 'P888' then options = { format = function( id ) return 'http://www.jstor.org/stable/' .. id end } end appendEntitySnaks( entityId, propertyId, data, parameterName, options ) end end end ---@param data source ---@return void local function expandPublication( data ) if not data[ 'publication-id' ] then return end local publicationId = getSingle( data[ 'publication-id' ] ) data.publication = {} for key, value in pairs( data ) do if not string.match( key, '^publication-' ) then data.publication[ key ] = value end end data.publication.sourceId = publicationId data.publication.title = data[ 'publication-title' ] data.publication.subtitle = data[ 'publication-subtitle' ] if data[ 'publication-qualifiers' ] then populateDataFromSnaks( data[ 'publication-qualifiers' ], data.publication, PUBLICATION_PROPERTY_MAP ) end populateDataFromEntity( publicationId, data.publication, PUBLICATION_PROPERTY_MAP ) if type( data.publication.title ) == 'table' and data.publication.title[ 1 ] then data.publication.title = data.publication.title[ 1 ] end if type( data.publication.subtitle ) == 'table' and data.publication.subtitle[ 1 ] then data.publication.subtitle = data.publication.subtitle[ 1 ] end for key, value in pairs( data.publication ) do if key ~= 'sourceId' and key ~= 'title' and key ~= 'subtitle' and key ~= 'url' and not data[ key ] then data[ key ] = value end end end ---@param data source ---@return void local function expandBookSeries( data ) local bookSeries = data.bookSeries if not bookSeries then return end -- use only first one if type( bookSeries ) == 'table' and bookSeries[ 1 ] and bookSeries[ 1 ].id then data.bookSeries = bookSeries[ 1 ] bookSeries = data.bookSeries end if not bookSeries or not bookSeries.id then return end appendEntitySnaks( bookSeries.id, 'P123', data, 'publisher', {} ) appendEntitySnaks( bookSeries.id, 'P291', data, 'place', {} ) appendEntitySnaks( bookSeries.id, 'P236', data, 'issn', {} ) end ---@param entityId string ---@return string | nil local function getNormativeTitle( entityId ) local possibleTypeIds = {} for typeId, _ in pairs( NORMATIVE_DOCUMENTS ) do table.insert( possibleTypeIds, typeId ) end local foundTypeId = getFirstType( entityId, possibleTypeIds ) if foundTypeId then return NORMATIVE_DOCUMENTS[ foundTypeId ] end return nil end ---@param urls table<number, string> | string ---@param text string ---@return string local function wrapInUrl( urls, text ) local url = getSingle( urls ) if string.sub( url, 1, 1 ) == ':' then return '[[' .. url .. '|' .. text .. ']]' else return '[' .. url .. ' ' .. text .. ']' end end ---@param entityId string ---@param lang string ---@return string local function getElementLink( entityId, lang ) local sitelink = getSitelink( entityId, nil ) if sitelink then return ':' .. sitelink end if lang ~= 'mul' then -- link to entity in source language sitelink = getSitelink( entityId, lang .. 'wiki' ) if sitelink then return ':' .. lang .. ':' .. sitelink end end return ':d:' .. entityId end ---@param entityId string ---@param lang string ---@return string local function getLabel( entityId, lang ) local wbStatus, label = pcall( mw.wikibase.getLabelByLang, entityId, lang ) if not wbStatus then return '' end if label and label ~= '' then return label end wbStatus, label = pcall( mw.wikibase.getLabel, entityId ) if not wbStatus then return '' end return label or '' end ---@param lang string ---@param entityId string ---@param customTitle string ---@param options table local function renderLink( lang, entityId, customTitle, options ) if not entityId then error( 'entityId is not specified' ) end if type( entityId ) ~= 'string' then error( 'entityId is not string, but ' .. type( entityId ) ) end if type( customTitle or '' ) ~= 'string' then error( 'customTitle is not string, but ' .. type( customTitle ) ) end local title = customTitle -- ISO 4 if isEmpty( title ) then local propertyStatements = getBestStatements( entityId, 'P1160' ) for _, claim in pairs( propertyStatements ) do if ( claim and claim.mainsnak and claim.mainsnak.datavalue and claim.mainsnak.datavalue.value and claim.mainsnak.datavalue.value.language == lang ) then title = claim.mainsnak.datavalue.value.text -- mw.log( 'Got title of ' .. entityId .. ' from ISO 4 claim: «' .. title .. '»' ) break end end end -- official name P1448 -- short name P1813 if isEmpty( title ) and options.short then local propertyStatements = getBestStatements( entityId, 'P1813' ) for _, claim in pairs( propertyStatements ) do if ( claim and claim.mainsnak and claim.mainsnak.datavalue and claim.mainsnak.datavalue.value and claim.mainsnak.datavalue.value.language == lang ) then title = claim.mainsnak.datavalue.value.text -- mw.log( 'Got title of ' .. entityId .. ' from short name claim: «' .. title .. '» (' .. lang .. ')' ) break end end end -- person name P1559 -- labels if isEmpty( title ) then title = getLabel( entityId, lang ) -- mw.log( 'Got title of ' .. entityId .. ' from label: «' .. title .. '» (' .. lang .. ')' ) end local actualText = title or '\'\'(untranslated)\'\'' local link = getElementLink( entityId, lang ) return wrapInUrl( link, actualText ) end ---@param lang string ---@param value value ---@param options options ---@return string local function asString( lang, value, options ) if type( value ) == 'string' then return options.format( value ) end if type( value ) ~= 'table' then return options.format( '(unknown type)' ) end if value.id then -- this is link if type( value.label or '' ) ~= 'string' then mw.logObject( value, 'error value' ) error( 'label of table value is not string but ' .. type( value.label ) ) end local title if options.preferids then title = value.id elseif options.nolinks then title = value.label or getLabel( value.id, lang ) else title = renderLink( lang, value.id, value.label, options ) end if title == '' then title = "''(untranslated title)''" end return options.format( title ) end local resultList = {} for _, tableValue in pairs( value ) do table.insert( resultList, asString( lang, tableValue, options ) ) end return mw.text.listToText( resultList, options.separator, options.conjunction ) end ---@param entityId string ---@param data source ---@return source local function populateSourceDataImpl( entityId, data, map ) local wsLink = getSitelink( entityId, 'ruwikisource' ) if wsLink and not mw.ustring.gmatch( wsLink, 'Категория:' ) then data.url = ":ru:s:" .. wsLink end populateDataFromEntity( entityId, data, map ) local normativeTitle = getNormativeTitle( entityId ) if normativeTitle then local y, m, d = mw.ustring.match( getSingle( data.dateOfCreation ) , "(%-?%d+)%-(%d+)%-(%d+)T" ) y, m, d = tonumber( y ),tonumber( m ), tonumber( d ) local title = asString( 'ru', data.title, options_commas_nolinks ) local docNumber = getSingle( data.docNumber ) data.title = { normativeTitle .. " от&nbsp;" .. tostring( d ) .. "&nbsp;" .. monthGen[ m ] .. " " .. tostring( y ) .. "&nbsp;г." .. ( docNumber and ( " №&nbsp;" .. docNumber ) or '' ) .. ' «' .. title.. '»' } end if not data.title then local lang = getLangCode( data.lang ) or i18nDefaultLanguage local label = getLabel( entityId, lang ) if label ~= '' then data.title = { label } end end return data end ---@param entityId string ---@param propertyId string ---@param data source ---@return void local function expandSpecialsQualifiers( entityId, propertyId, data ) local statements = getBestStatements( entityId, propertyId ) for _, statement in pairs( statements ) do populateDataFromSnaks( statement.qualifiers or {}, data, PROPERTY_MAP ) end end ---Expand special types of references when additional data could be found in OTHER entity properties ---@param data source ---@return void local function expandSpecials( data ) if not data.entityId then return end if data.sourceId == 'Q36578' then -- Gemeinsame Normdatei -- specified by P227 appendEntitySnaks( data.entityId, 'P227', data, 'part', { format = function(gnd ) return 'Record #' .. gnd; end } ) appendEntitySnaks( data.entityId, 'P227', data, 'url', { format = function(gnd ) return 'http://d-nb.info/gnd/' .. gnd .. '/'; end } ) data.year = '2012—2016' expandSpecialsQualifiers( data.entityId, 'P227', data ) elseif data.sourceId == 'Q15222191' then -- BNF -- specified by P268 appendEntitySnaks( data.entityId, 'P268', data, 'part', { format = function(id ) return 'Record #' .. id; end } ) appendEntitySnaks( data.entityId, 'P268', data, 'url', { format = function(id ) return 'http://catalogue.bnf.fr/ark:/12148/cb' .. id; end } ) expandSpecialsQualifiers( data.entityId, 'P268', data ) elseif data.sourceId == 'Q54919' then -- VIAF -- specified by P214 appendEntitySnaks( data.entityId, 'P214', data, 'part', { format = function(id ) return 'Record #' .. id; end } ) appendEntitySnaks( data.entityId, 'P214', data, 'url', { format = function(id ) return 'https://viaf.org/viaf/' .. id; end } ) expandSpecialsQualifiers( data.entityId, 'P214', data ) else -- generic property search for _, sourceClaim in pairs( getBestStatements( data.sourceId, 'P1687' ) ) do if sourceClaim.mainsnak.snaktype == 'value' then local sourcePropertyId = sourceClaim.mainsnak.datavalue.value.id for _, sourcePropertyClaim in pairs( getBestStatements( sourcePropertyId, 'P1630' ) ) do if sourcePropertyClaim.mainsnak.snaktype == 'value' then appendEntitySnaks( data.entityId, sourcePropertyId, data, 'url', { format = function( id ) return mw.ustring.gsub( mw.ustring.gsub( sourcePropertyClaim.mainsnak.datavalue.value, '$1', id ), ' ', '%%20' ) end } ) expandSpecialsQualifiers( data.entityId, sourcePropertyId, data ) break end end end end end -- do we have appropriate record in P1433 ? local claims = findClaimsByValue( currentEntityId, 'P1343', data.sourceId ) if claims and #claims ~= 0 then for _, claim in pairs( claims ) do populateDataFromSnaks( claim.qualifiers, data, PROPERTY_MAP ) populateDataFromEntity( data.sourceId, data, PROPERTY_MAP ) end end end ---@param text string ---@param tip string ---@return string local function toTextWithTip( text, tip ) return '<span title="' .. tip .. '" style="border-bottom: 1px dotted; cursor: help; white-space: nowrap">' .. text .. '</span>' end ---@param lang string ---@param placeId string ---@return string local function getPlaceName( placeId, lang ) -- ГОСТ Р 7.0.12—2011 if lang == 'ru' then if placeId == 'Q649' then return toTextWithTip( 'М.', 'Москва' ); end if placeId == 'Q656' then return toTextWithTip( 'СПб.', 'Санкт-Петербург' ); end if placeId == 'Q891' then return toTextWithTip( 'Н. Новгород', 'Нижний Новгород' ); end if placeId == 'Q908' then return toTextWithTip( 'Ростов н/Д.', 'Ростов-на-Дону' ); end end return nil end ---@param data source ---@param lang string ---@return void local function preprocessPlace( data, lang ) if not data.place then return end ---@type table<number, string> local newPlace = {} for index, place in pairs( data.place ) do if place.id then local newPlaceStr = getPlaceName( place.id, lang ) if newPlaceStr then newPlace[ index ] = newPlaceStr else newPlace[ index ] = getLabel( place.id, lang ) end else newPlace[ index ] = place end end data.place = newPlace end ---@param entityId string ---@param lang string ---@param providedLabel string | nil ---@param options options ---@return string local function getPersonNameAsLabel( entityId, lang, providedLabel, options ) -- would custom label provided we don't need to check entity at all if not isEmpty( providedLabel ) then return options.format( providedLabel ) end if lang == 'mul' then lang = i18nDefaultLanguage end ---@type string | nil local personName = getLabel( entityId, lang ) if isEmpty( personName ) then return '\'\'(not translated to ' .. lang .. ')\'\'' end if not isInstanceOf( entityId, 'Q5' ) then return personName end return options.format( personName ) end ---@param entityId string ---@param lang string ---@param customLabel string | nil ---@param options options ---@return string local function getPersonNameAsWikitext( entityId, lang, customLabel, options ) local personName = getPersonNameAsLabel( entityId, lang, customLabel, options ) local link = getElementLink( entityId, lang ) return wrapInUrl( link, personName ) end ---@param value value ---@param lang string ---@param options options ---@return string local function getPeopleAsWikitext( value, lang, options ) if type( value ) == 'string' then return options.format( value ) elseif type( value ) == 'table' then if value.id then -- this is link if options.preferids then return tostring( value.id ) else if options.nolinks then return getPersonNameAsLabel( value.id, lang, value.label, options ) else return getPersonNameAsWikitext( value.id, lang, value.label, options ) end end end local maxAuthors = 10 -- need some restrictions, as some publications have enormous amount of authors (e.g. 115 authors of Q68951544) local resultList = {} for _, tableValue in pairs( value ) do local nextWikitext = getPeopleAsWikitext( tableValue, lang, options ) if not isEmpty( nextWikitext ) then table.insert( resultList, nextWikitext ) if #resultList == maxAuthors + 1 then -- keep one more to indicate that there are too many break end end end local resultWikitext = '' for i, wikitext in pairs( resultList ) do if i == maxAuthors + 1 then resultWikitext = resultWikitext .. ( i18nEtAl[ lang ] or i18nEtAlDefault ) break end if i ~= 1 then resultWikitext = resultWikitext .. ', ' end resultWikitext = resultWikitext .. wikitext end return resultWikitext end return '' -- options.format( '(unknown type)' ) end ---@param lang string ---@param data source ---@return string local function generateAuthorLinks( lang, data ) local result = '' if data.author then result = getPeopleAsWikitext( data.author, lang, options_commas_authors ) result = '<i class="wef_low_priority_links">' .. result .. '</i> ' end return result end ---@param lang string ---@param data source ---@param conjunction string ---@param propertyName string ---@param urlPropertyName string? ---@return string local function appendProperty( lang, data, conjunction, propertyName, urlPropertyName ) if not data[ propertyName ] then return '' end local out if urlPropertyName and data[ urlPropertyName ] then out = wrapInUrl( data[ urlPropertyName ], asString( lang, data[ propertyName ], options_commas_nolinks ) ) else out = asString( lang, data[ propertyName ], options_commas ) end if not out or out == '' then return '' end return conjunction .. out end ---@param lang string ---@param data source ---@return string local function appendTitle( lang, data ) local conjunction = '' local result = '' if data.part then result = result .. appendProperty( lang, data, '', 'part', 'parturl' ) conjunction = ' // ' end return result .. appendProperty( lang, data, conjunction, 'title', 'url' ) end ---@param lang string ---@return string local function appendLanguage( lang ) if lang == i18nDefaultLanguage then return '' end ---@type { getRefHtml: ( fun( lang: string ): string ), list_ref: ( fun( frame: frame ): string ) } local langs = require( 'Module:Languages' ) return langs.list_ref( p.currentFrame:newChild{ args = { lang } } ) end ---@param lang string ---@param data source ---@return string local function appendSubtitle( lang, data ) return appendProperty( lang, data, ': ', 'subtitle', nil ) end ---@param lang string ---@param data source ---@return string local function appendOriginalTitle( lang, data ) return appendProperty( lang, data, ' = ', 'originaltitle', nil ) end ---@param lang string ---@param data source ---@return string local function appendPublication( lang, data ) if not data.publication then return '' end local result = ' // ' .. asString( lang, data.publication.title, options_commas_it_short ) if data.publication.subtitle and data.publication.subtitle ~= '' then result = result .. ': ' .. asString( lang, data.publication.subtitle, options_commas_it_short ) end return result end ---@param lang string ---@param data source ---@return string local function appendEditor( lang, data ) if not data.editor and not data.translator then return '' end local result = ' / ' if data.editor then local prefix = i18nEditors[ lang ] or i18nEditors[ i18nDefaultLanguage ] result = result .. prefix .. getPeopleAsWikitext( data.editor, lang, options_commas_responsible ) if data.translator then result = result .. ', ' end end if data.translator then local prefix = i18nTranslators[ lang ] or i18nTranslators[ i18nDefaultLanguage ] result = result .. prefix .. getPeopleAsWikitext( data.translator, lang, options_commas_responsible ) end return result end ---@param lang string ---@param data source local function appendEdition( lang, data ) return appendProperty( lang, data, ' — ', 'edition', nil ) end ---@param lang string ---@param data source ---@return string local function appendPublicationData( lang, data ) if not data.place and not data.publisher and not data.year then return '' end local result = ' — ' if data.place then result = result .. asString( lang, data.place, options_commas_short ) if data.publisher or data.year then result = result .. ': ' end end if data.publisher then result = result .. asString( lang, data.publisher, options_commas_short ) if data.year then result = result .. ', ' end end if data.year then result = result .. asString( lang, data.year, options_commas ) end result = result .. '.' return result end ---@param lang string ---@param data source ---@return string local function appendVolumeAndIssue( lang, data ) if not data.volume and not data.issue then return '' end local result = ' — ' local letter_vol = i18nVolume[ lang ] or i18nVolume[ i18nDefaultLanguage ] local letter_iss = i18nIssue[ lang ] or i18nIssue[ i18nDefaultLanguage ] if data.volume then result = result .. appendProperty( lang, data, letter_vol .. '&nbsp;', 'volume', nil ) result = result ..appendProperty( lang, data, ', ' .. letter_iss .. '&nbsp;', 'issue', nil ) else result = result .. appendProperty( lang, data, letter_iss .. '&nbsp;', 'issue', nil ) end result = result .. '.' return result end ---@param lang string ---@param data source ---@return string local function appendPages( lang, data ) if not data.pages then return '' end local letter = i18nPages[ lang ] or i18nPages[ i18nDefaultLanguage ] local strPages = asString( lang, data.pages, options_commas ) strPages = mw.ustring.gsub( strPages, '[-—]', '—' ) return ' — ' .. letter .. '&nbsp;' .. strPages .. '.' end ---@param lang string ---@param data source ---@return string local function appendNumberOfPages( lang, data ) if not data.numberOfPages then return '' end local letter = i18nNumberOfPages[ lang ] or i18nNumberOfPages[ i18nDefaultLanguage ] return appendProperty( lang, data, ' — ', 'numberOfPages', nil ) .. '&nbsp;' .. letter end ---@param lang string ---@param data source ---@return string local function appendBookSeries( lang, data ) if not data.bookSeries then return '' end local result = appendProperty( lang, data, ' — (', 'bookSeries', nil ) if data.bookSeriesVolume or data.bookSeriesIssue then result = result .. '; ' local letter_vol = i18nVolume[ lang ] or i18nVolume[ i18nDefaultLanguage ] local letter_iss = i18nIssue[ lang ] or i18nIssue[ i18nDefaultLanguage ] if data.bookSeriesVolume then result = result .. appendProperty( lang, data, letter_vol .. '&nbsp;', 'bookSeriesVolume', nil ) result = result .. appendProperty( lang, data, ', ' .. letter_iss .. '&nbsp;', 'bookSeriesIssue', nil ) else result = result .. appendProperty( lang, data, letter_iss .. '&nbsp;', 'bookSeriesIssue', nil ) end end result = result .. ')' return result end ---@param lang string ---@param data source ---@return string local function appendTirage( lang, data ) if not data.tirage then return '' end local tirageTemplate = i18nTirage[ lang ] or i18nTirage[ i18nDefaultLanguage ] ---@type options local optionsTirage = { separator = '; ', conjunction = '; ', format = function( _data ) return tostring( mw.ustring.format( tirageTemplate, _data ) ) end, short = false, nolinks = false, preferids = false, } return ' — ' .. asString( lang, data.tirage, optionsTirage ) end ---@param lang string ---@param value string | nil ---@param options options ---@param prefix string? ---@return string local function appendIdentifier( lang, value, options, prefix ) if not value then return '' end return ' — ' .. ( prefix or '' ) .. asString( lang, value, options ) end ---@param result string ---@param lang string ---@param data source ---@return string local function wrapSourceId( result, lang, data ) if not data.sourceId then return result end local citeType = data.type and asString( lang, data.type, options_citetypes ) or 'citetype_unknown' return '<span class="wikidata_cite ' .. citeType .. '" data-entity-id="' .. data.sourceId .. '">' .. result .. '</span>' end ---@param data source ---@return string local function appendAccessDate( data ) if not data.accessdate then return '' end local date = getSingle( data.accessdate ) local pattern = "(%-?%d+)%-(%d+)%-(%d+)T" local y, m, d = mw.ustring.match( date, pattern ) y, m, d = tonumber( y ), tonumber( m ), tonumber( d ) local date_str = ( d > 0 and ' ' .. tostring( d ) or '' ) .. ( m > 0 and ' ' .. monthGen[ m ] or '' ) .. ( y > 0 and ' ' .. tostring( y ) or '' ) return " <small>Проверено" .. date_str .. ".</small>" end ---@param data source ---@param lang string ---@return void local function populateUrl( data, lang ) if data.sourceId and not data.url then local sitelink = getSitelink( data.sourceId, lang .. 'wikisource' ) if sitelink then data.url = ':' .. lang .. ':s:' .. sitelink end end end ---@param data source ---@return void local function populateYear( data ) if not data.year and data.dateOfPublication then local date = getSingle( data.dateOfPublication ) data.year = mw.ustring.sub( date, 2, 5 ) end if not data.year and data.dateOfCreation then local date = getSingle( data.dateOfCreation ) data.year = mw.ustring.sub( date, 2, 5 ) end end ---@param data source ---@return void local function populateTitle( data ) data.title = data.title or getSingle( data.url ) end ---@param data source ---@return string local function renderSource( data ) local lang = getLangCode( data.lang ) or i18nDefaultLanguage preprocessPlace( data, lang ) populateUrl( data, lang ) populateTitle( data ) if not data.title then return '' end populateYear( data ) local result = generateAuthorLinks( lang, data ) result = result .. appendTitle( lang, data ) result = result .. appendLanguage( lang ) result = result .. appendSubtitle( lang, data ) result = result .. appendOriginalTitle( lang, data ) result = result .. appendPublication( lang, data ) result = result .. '<span class="wef_low_priority_links">' result = result .. appendEditor( lang, data ) -- Might take current editor instead of actual. Use with caution result = result .. appendEdition( lang, data ) result = result .. appendPublicationData( lang, data ) result = result .. appendVolumeAndIssue( lang, data ) result = result .. appendPages( lang, data ) result = result .. appendNumberOfPages( lang, data ) result = result .. appendBookSeries( lang, data ) result = result .. appendTirage( lang, data ) result = result .. appendIdentifier( lang, data.isbn, options_commas, 'ISBN ' ) result = result .. appendIdentifier( lang, data.issn, options_issn, 'ISSN ' ) result = result .. appendIdentifier( lang, data.doi, options_doi, nil ) result = result .. appendIdentifier( lang, data.pmid, options_pmid, nil ) result = result .. appendIdentifier( lang, data.arxiv, options_arxiv, nil ) result = result .. appendAccessDate( data ) result = result .. '</span>' return wrapSourceId( result, lang, data ) end ---@param data source Данные в простом формате, согласованном с модулями формирования библиографического описания ---@param snaks snaks ---@return string | nil local function renderReferenceImpl( data, snaks ) -- не показывать источники с "импортировано из" if snaks.P143 then return nil end -- забрать данные из reference populateDataFromSnaks( snaks or {}, data, PROPERTY_MAP ) data.sourceId = getSingle( data.sourceId ) populateDataFromEntity( data.sourceId, data, PROPERTY_MAP ) expandSpecials( data ) populateSourceDataImpl( data.sourceId, data, PROPERTY_MAP ) expandPublication( data ) expandBookSeries( data ) if next( data ) == nil then return nil end local rendered = renderSource( data ) if mw.ustring.len( rendered ) == 0 then return nil end if data.ref then local anchorValue = 'CITEREF' .. data.ref .. ( coalesce( { data[ 'ref-year' ], data.year } ) or '' ) rendered = '<span class="citation" id="' .. mw.uri.anchorEncode( anchorValue ) .. '">' .. rendered .. '</span>' end return rendered end ---@param frame frame ---@param currentEntityId string | { id: string } ---@param reference table{ snaks: snaks } ---@return string | nil function p.renderSource( frame, currentEntityId, reference ) reference = reference or { snaks = {} } p.currentFrame = frame local data = getFilledArgs( frame.args or {} ) populateDataFromSnaks( reference.snaks, data, PROPERTY_MAP ) data.sourceId = getSingle( data.sourceId ) if not currentEntityId then data.entityId = mw.wikibase.getEntityIdForCurrentPage() elseif type( currentEntityId ) == 'string' then data.entityId = currentEntityId elseif type( currentEntityId ) == 'table' and currentEntityId.id then data.entityId = currentEntityId.id end ---@type string local rendered = renderReferenceImpl( data, reference.snaks or {} ) if not rendered then return '' end return rendered end ---@param frame frame ---@param currentEntityId string ---@param reference table ---@return string function p.renderReference( frame, currentEntityId, reference ) local rendered = p.renderSource( frame, currentEntityId, reference ) if not rendered or rendered == '' then return '' end -- Про выбор алгоритма хеширования см. [[Модуль:Hash]]. Знак подчёркивания в начале позволяет -- исключить ошибку, когда имя сноски — чисто числовое значение, каковыми иногда бывают хеши. return frame:extensionTag( 'ref', rendered, { name = '_' .. mw.hash.hashValue( 'fnv164', rendered ) } ) .. '[[Category:Википедия:Статьи с источниками из Викиданных]]' end ---@param frame frame ---@return string | nil function p.testPersonNameToAuthorName( frame ) return personNameToAuthorName( frame.args[ 1 ] ) end ---@param frame frame ---@return string | nil function p.testPersonNameToResponsibleName( frame ) return personNameToResponsibleName( frame.args[ 1 ] ) end return p 752a204827a41ecd6cf518bdb22da12718bca2ec Шаблон:Заглавная/styles.css 10 8 18 2024-06-13T19:33:39Z ruwiki>Stjn 0 fix sanitized-css text/css /* Новое оформление [[Заглавная страница]] Главный референс: https://design.wikimedia.org/style-guide/ https://github.com/wikimedia/wikimedia-ui-base/blob/master/wikimedia-ui-base.less Не удаляйте код до завершения работы */ /* Стандартные заголовки */ .main-header.main-header.main-header { border-bottom-color: transparent; margin-bottom: 0.25em; margin-top: 0; padding-bottom: 0; padding-top: 0; } body.skin-minerva .main-block h1, body.skin-minerva .main-block h2 { /* хак для Минервы в связи с [[mw:Heading HTML changes]] */ display: block; } body.skin-timeless .main-header.main-header.main-header { border-bottom-color: transparent; } /* Списки без оформления */ .main-plainlist ul { list-style: none; margin: 0; padding: 0; } .main-plainlist li { margin-bottom: 0; } /* Убираем нумерацию заголовков, создаваемую опцией «Автоматически нумеровать заголовки» на [[Служебная:Настройки#mw-prefsection-rendering]] */ .main-block .mw-headline-number { display: none; } /* Скопировано из [[:w:Template:Screen reader-only/styles.css]] */ .main-block .sr-only { border: 0; clip: rect(0, 0, 0, 0); /* Removed from CSS specification */ /* clip-path is the replacement for clip, but very few browsers support it. */ clip-path: polygon(0px 0px, 0px 0px, 0px 0px); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; white-space: nowrap; } /* Планшеты */ @media (min-width: 720px) { .main-wikimedia { padding-left: 1rem; padding-right: 1rem; } } /* Стационарные компьютеры */ @media (min-width: 1000px) { .main-wrapper { display: flex; gap: 1.5rem; /* Fixes https://phabricator.wikimedia.org/F54943102 */ flex-wrap: wrap; } .main-wrapper-column { flex: 1; } .main-wikimedia { padding-left: 1.5rem; padding-right: 1.5rem; } } /* [[Категория:Шаблоны:Подстраницы CSS]] */ 22963811044f787be151a02e4e09cbdc96d990d3 Модуль:Message box/ombox.css 828 68 108 2024-06-21T16:47:35Z ruwiki>Putnik 0 исправление цвета рамки sanitized-css text/css /* Скопировано из [[:en:Module:Message box/ombox.css]] */ .ombox { margin: 4px 0; border-collapse: collapse; border: 1px solid var(--border-color-base, #a2a9b1); /* Default "notice" gray */ background-color: var(--background-color-neutral-subtle, #f8f9fa); box-sizing: border-box; } /* For the "small=yes" option. */ .ombox.mbox-small { font-size: 88%; line-height: 1.25em; } .ombox-speedy { border: 2px solid var(--border-color-error, #b32424); /* Red */ background-color: var(--background-color-error-subtle, #fee7e6); /* Pink */ } .ombox-delete { border: 2px solid var(--background-color-error--active, #b32424); /* Red */ } .ombox-content { border: 1px solid #f28500; /* Orange */ } .ombox-style { border: 1px solid #fc3; /* Yellow */ } .ombox-move { border: 1px solid #9932cc; /* Purple */ } .ombox-protection { border: 2px solid var(--border-color-base, #a2a9b1); /* Gray-gold */ } .ombox .mbox-text { border: none; /* @noflip */ padding: 0.25em 0.9em; width: 100%; } .ombox .mbox-image { border: none; /* @noflip */ padding: 2px 0 2px 0.9em; text-align: center; } .ombox .mbox-imageright { border: none; /* @noflip */ padding: 2px 0.9em 2px 0; text-align: center; } /* An empty narrow cell */ .ombox .mbox-empty-cell { border: none; padding: 0; width: 1px; } .ombox .mbox-invalid-type { text-align: center; } /* Хак, TODO: посмотреть, как оно на самом деле работает */ .ombox .mbox-textsmall-div { font-size: 90%; } @media (min-width: 720px) { .ombox { margin: 4px 10%; } .ombox.mbox-small { /* @noflip */ clear: right; /* @noflip */ float: right; /* @noflip */ margin: 4px 0 4px 1em; width: 238px; } /* Стили нотификаций для ноутбуков */ @media (max-width: 1366px) { .ombox { margin-left: 6%; margin-right: 6%; } } } /* [[Категория:Модули:Подстраницы CSS]] */ 6627874170f6674674bfa5796b2f7dfb6698cd81 Шаблон:Doc/begin 10 172 386 2024-06-30T22:14:58Z ruwiki>Putnik 0 [[ВП:×|отмена]] правки 138443392 участника [[Special:Contribs/Putnik|Putnik]] ([[UT:Putnik|обс.]]) wikitext text/x-wiki <includeonly><templatestyles src="Шаблон:Doc/styles.css" /> <div class="ts-doc-doc" id="doc"> <div class="ts-doc-header" id="Документация"> <div class="ts-doc-heading">Документация</div> {{#if: {{{inline|}}} || {{Действия для страницы|lc={{{1}}}|nowatch=yes}} }} </div> <div class="ts-doc-content"></includeonly><noinclude> {{doc}} </noinclude> c753f0a9f65d86707cdffaf93fb49c2c52daf92b Модуль:Message box/configuration 828 67 106 2024-07-05T22:32:41Z ruwiki>Putnik 0 временное исправление шаблонов обсуждений через .notheme Scribunto text/plain -------------------------------------------------------------------------------- -- Message box configuration -- -- -- -- This module contains configuration data for [[Module:Message box]]. -- -------------------------------------------------------------------------------- return { ambox = { types = { speedy = { class = 'ambox-speedy', image = 'Ambox warning pn.svg' }, delete = { class = 'ambox-delete', image = 'Stop hand nuvola.svg' }, content = { class = 'ambox-content', image = 'Emblem-important.svg' }, style = { class = 'ambox-style', image = 'Broom_icon.svg' }, move = { class = 'ambox-move', image = 'Merge-split-transwiki default.svg' }, protection = { class = 'ambox-protection', image = 'Padlock-silver-medium.svg' }, notice = { class = 'ambox-notice', image = 'Information.svg' }, good = { class = 'ambox-good', image = 'Green star boxed.svg' }, serious = { class = 'ambox-serious', image = 'Stop hand nuvola.svg' }, merge = { class = 'ambox-merge', image = 'Merge-split-transwiki default.svg' }, discussion = { class = 'ambox-discussion', image = 'Nuvola apps ksirc.png' } }, default = 'notice', allowBlankParams = {'talk', 'sect', 'date', 'issue', 'fix', 'subst', 'hidden', 'image'}, allowSmall = true, smallParam = 'left', smallClass = 'mbox-small-left', substCheck = true, classes = {'metadata', 'ambox'}, imageEmptyCell = true, imageCheckBlank = true, imageSmallSize = '20x20px', imageCellDiv = true, useCollapsibleTextFields = true, imageRightNone = true, sectionDefault = 'статья', allowMainspaceCategories = true, templateCategory = 'Шаблоны:Шаблоны-сообщения для статей', templateCategoryRequireName = true, templateErrorCategory = 'Шаблоны:Шаблоны-сообщения для статей с пропущенными параметрами', templateErrorParamsToCheck = {'issue', 'fix'}, removalNotice = '[[Help:Maintenance template removal|Learn how and when to remove this template message]]', templatestyles = 'Module:Message box/ambox.css', }, cmbox = { types = { speedy = { class = 'cmbox-speedy notheme', image = 'Ambox warning pn.svg' }, delete = { class = 'cmbox-delete notheme', image = 'Ambox warning pn.svg' }, content = { class = 'cmbox-content notheme', image = 'Ambox important.svg' }, style = { class = 'cmbox-style notheme', image = 'Edit-clear.svg' }, move = { class = 'cmbox-move notheme', image = 'Merge-split-transwiki default.svg' }, protection = { class = 'cmbox-protection notheme', image = 'Padlock-silver-medium.svg' }, notice = { class = 'cmbox-notice notheme', image = 'Information icon4.svg' } }, default = 'notice', showInvalidTypeError = true, classes = {'cmbox'}, imageEmptyCell = true, useCollapsibleTextFields = true, templatestyles = 'Module:Message box/cmbox.css', }, fmbox = { types = { warning = { class = 'fmbox-warning', image = 'Ambox warning pn.svg' }, editnotice = { class = 'fmbox-editnotice', image = 'Information icon4.svg' }, system = { class = 'fmbox-system', image = 'Information icon4.svg' } }, default = 'system', showInvalidTypeError = true, classes = {'fmbox'}, imageEmptyCell = false, imageRightNone = false, useCollapsibleTextFields = true, templatestyles = 'Module:Message box/fmbox.css', }, imbox = { types = { speedy = { class = 'imbox-speedy', image = 'Ambox warning pn.svg' }, delete = { class = 'imbox-delete', image = 'Ambox warning pn.svg' }, content = { class = 'imbox-content', image = 'Ambox important.svg' }, style = { class = 'imbox-style', image = 'Edit-clear.svg' }, move = { class = 'imbox-move', image = 'Merge-split-transwiki default.svg' }, protection = { class = 'imbox-protection', image = 'Padlock-silver-medium.svg' }, license = { class = 'imbox-license licensetpl', image = 'Imbox license.png' -- @todo We need an SVG version of this }, featured = { class = 'imbox-featured', image = 'Cscr-featured.svg' }, notice = { class = 'imbox-notice', image = 'Information icon4.svg' } }, default = 'notice', showInvalidTypeError = true, classes = {'imbox'}, imageEmptyCell = true, below = true, useCollapsibleTextFields = true, templateCategory = 'Шаблоны:Шаблоны-сообщения для файлов', templatestyles = 'Module:Message box/imbox.css', }, ombox = { types = { speedy = { class = 'ombox-speedy', image = 'OOjs UI icon alert-destructive.svg' }, delete = { class = 'ombox-delete', image = 'OOjs UI icon alert-destructive.svg' }, content = { class = 'ombox-content', image = 'OOjs UI icon notice-warning.svg' }, style = { class = 'ombox-style', image = 'Edit-clear.svg' }, move = { class = 'ombox-move', image = 'Imbox move.png' }, protection = { class = 'ombox-protection', image = 'Imbox protection.png' }, notice = { class = 'ombox-notice', image = 'OOjs UI icon info-progressive.svg' } }, default = 'notice', showInvalidTypeError = true, classes = {'ombox'}, allowSmall = true, imageEmptyCell = true, imageRightNone = true, useCollapsibleTextFields = true, templatestyles = 'Module:Message box/ombox.css', }, tmbox = { types = { speedy = { class = 'tmbox-speedy notheme', image = 'Ambox warning pn.svg' }, delete = { class = 'tmbox-delete notheme', image = 'Ambox warning pn.svg' }, content = { class = 'tmbox-content notheme', image = 'Ambox important.svg' }, style = { class = 'tmbox-style notheme', image = 'Edit-clear.svg' }, move = { class = 'tmbox-move notheme', image = 'Merge-split-transwiki default.svg' }, protection = { class = 'tmbox-protection notheme', image = 'Padlock-silver-medium.svg' }, notice = { class = 'tmbox-notice notheme', image = 'Information icon4.svg' } }, default = 'notice', showInvalidTypeError = true, classes = {'tmbox'}, allowSmall = true, imageRightNone = true, imageEmptyCell = true, imageEmptyCellStyle = true, useCollapsibleTextFields = true, templateCategory = 'Шаблоны:Шаблоны-сообщения для страниц обсуждений', templatestyles = 'Module:Message box/tmbox.css', } } dd71cfc9b05d5244df926bfe86dfdb7ad0e0ff85 Модуль:Navbar 828 87 148 2024-07-08T20:00:10Z ruwiki>Putnik 0 более контрастная серая иконка шестерёнки в тёмной теме Scribunto text/plain local p = {} local hlist = 'Template:Flatlist/styles.css' local templatestyles = 'Module:Navbar/styles.css' local getArgs function p._ruwikiNavbar( args ) local titleText = args[ 1 ] or (':' .. mw.getCurrentFrame():getParent():getTitle()) local title = mw.title.new(mw.text.trim(titleText), 'Template'); if not title then error('Invalid title ' .. titleText) end local whiteColorDefs = { ['#fff'] = true, ['#ffffff'] = true, ['white'] = true, } local fontColor = args.fontcolor and args.fontcolor:lower() local isWhite = fontColor and whiteColorDefs[ fontColor ] == true local fontStyle = args.fontstyle and mw.text.unstripNoWiki( args.fontstyle:lower() ) if not isWhite and fontStyle then local styleratio = require( 'Module:Color contrast' )._styleratio isWhite = styleratio( { fontStyle .. '; color:#666;', '', '#666' } ) < 3.66 end local isTemplate = title.namespace == 10 local altText = string.format( 'Перейти %s «%s»', isTemplate and 'к шаблону' or 'на страницу', mw.text.split( isTemplate and title.text or title.fullText, '#' )[ 1 ] ) return string.format( '[[Файл:Wikipedia interwiki section gear icon%s.svg|14px|class=noprint%s|link=%s|%s]]', isWhite and ' white' or '', isWhite and '' or ' skin-invert-image', tostring( title ), altText ) end function p.ruwikiNavbar(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end return p._ruwikiNavbar(getArgs(frame)) end function p._navbar(args) local titleArg = 1 if args.collapsible then titleArg = 2 if not args.plain then args.mini = 1 end if args.fontcolor then args.fontstyle = 'color:' .. args.fontcolor .. ';' end args.style = 'float:left; text-align:left; white-space:nowrap;' end if args[titleArg] == 'off' then return end local titleText = args[titleArg] or (':' .. mw.getCurrentFrame():getParent():getTitle()) local title = mw.title.new(mw.text.trim(titleText), 'Template'); if not title then error('Invalid title ' .. titleText) end local talkpage = title.talkPageTitle and title.talkPageTitle.fullText or ''; local tag if args.nodiv then tag = 'span' else tag = 'div' end local div = mw.html.create():tag(tag) div :addClass('navbar hlist plainlinks noprint') :attr('data-navboxnavigation-link', '0') :cssText(args.style) if args.mini then div:addClass('navbar-mini') end if not (args.mini or args.plain) then div :tag('span') :addClass('navbar-boxtext') :cssText(args.fontstyle) :wikitext(args.text or 'Шаблон:') :wikitext(' ') end local ul = div:tag('ul'); if args.brackets then ul:addClass('navbar-brackets') end ul :tag('li') :addClass('nv-view') :wikitext('[[' .. title.fullText .. '|') :tag(args.mini and 'abbr' or 'span') :addClass(args.mini and 'navbar-mini-abbr') :attr('title', 'Просмотр этого шаблона') :cssText(args.fontstyle) :wikitext(args.mini and 'п' or 'просмотр') :done() :wikitext(']]') :done() :tag('li') :addClass('nv-talk') :wikitext('[[' .. talkpage .. '|') :tag(args.mini and 'abbr' or 'span') :attr('title', 'Обсуждение этого шаблона') :cssText(args.fontstyle) :wikitext(args.mini and 'о' or 'обсуждение') :done() :wikitext(']]'); if not args.noedit then ul :tag('li') :addClass('nv-edit') :wikitext('[[Special:EditPage/' .. title.fullText .. '|') :tag(args.mini and 'abbr' or 'span') :attr('title', 'Править этот шаблон') :cssText(args.fontstyle) :wikitext(args.mini and 'р' or 'править') :done() :wikitext(']]'); end if args.collapsible then div:done() :tag('span') :addClass( args.mini and 'navbar-ct-mini' or 'navbar-ct-full' ) :cssText(args.fontstyle) :wikitext(args[1]) end local frame = mw.getCurrentFrame() return frame:extensionTag{ name = 'templatestyles', args = { src = hlist } } .. frame:extensionTag{ name = 'templatestyles', args = { src = templatestyles } } .. tostring(div:done()) end function p.navbar(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end return p._navbar(getArgs(frame)) end return p 695777e4dafbd5f7bf8b4f35d8db9349d08a363d Модуль:Wikidata/doc 828 208 464 2024-07-28T13:08:16Z ruwiki>Putnik 0 добавлены тесты wikitext text/x-wiki {{СИШ}} {{module rating|p}} {{TOC right}} Используется в {{tl|Wikidata}} (см. описания параметров там же). Настраивается при помощи [[Модуль:Wikidata/config]]. Прежде чем вносить какие-либо изменения в данный модуль, просьба оттестировать их в [[Модуль:Wikidata/песочница|/песочнице]]. Обратите внимание, что не всё корректно работает в песочнице. == Общие сведения == Функции данного модуля не предназначены для прямого вызова из шаблонов карточек или других модулей, не являющихся функциями расширения данного. Для вызова из шаблонов карточек используйте шаблон {{tl|wikidata}} или один из специализированных шаблонов для свойств. Для вызова функций Викиданных предназначенных для отображения чаще всего достаточно вызова <code>frame:expandTemplate{}</code> с вызовом шаблона, ответственного за отрисовку свойства. С другой стороны, вызов определённых функций модуля (в основном это касается <code>getEntity()</code>) может в будущем стать предпочтительным. Данный Lua-функционал в любом случае стоит рассматривать как unstable с точки зрения сохранения совместимости на уровне кода (вместе с соответствующими функциями API для Wikibase Client). Далее описывается внутренняя документация. Названия функций и параметров могут изменяться. При их изменении автор изменений обязан обновить шаблон {{tl|wikidata}} и специализированные шаблоны свойств. Изменения в других местах, если кто-то всё-таки вызывает функции модуля напрямую, остаются на совести автора «костыля». Итак, при вызове шаблона {{tl|wikidata}} или специализированного шаблона свойства управление отдаётся на функцию formatStatements, которая принимает frame. Из frame достаются следующие опции, которые так или иначе передаются в остальные функции: * <code>plain</code> — булевый переключатель (по умолчанию false). Если true, результат совпадает с обычным вызовом <code><nowiki>{{#property:pNNN}}</nowiki></code> (по факту им и будет являться) * <code>references</code> — булевый переключатель (по умолчанию true). Если true, после вывода значения параметра дополнительно выводит ссылки на источники, указанные в Викиданных. Для вывода используется [[Модуль:Sources]]. Обычно отключается для тех свойств, которые являются «самоописываемыми», например, внешними идентификаторами или ссылками (когда такая ссылка является доказательством своей актуальности), например, идентификаторы IMDb. * <code>value</code> — значение, которое надо выводить ''вместо'' значений из Викиданных (используется, если что-то задано уже в карточке в виде т. н. локального свойства) По умолчанию модуль поддерживает вывод следующих значений без дополнительных настроек: * географические координаты (coordinates) * количественные значения (quantity) * моноязычный текст (monolingualtext) * строки (string) * даты (time) Остальные типы данных требуют указания функции форматирования значения. == Кастомизация == Поддерживаются три типа параметров-функций, которые дополнительно указывают, как надо форматировать значения: * <code>property-module</code>, <code>property-function</code> — название модуля и функции модуля, которые отвечают за форматирование вывода массива значений ''свойства'' (property) с учётом квалификаторов, ссылок и прочего. Например, оформляет множество выводов в таблицу или график. Характерные примеры: ** вывод таблицы и графика населения в {{tl|wikidata/Population}} и [[Модуль:Wikidata/Population]]. *: Спецификация функции: <code>function p.…( context, options )</code>, поведение по умолчанию: [[Модуль:Wikidata#formatPropertyDefault]]. * <code>claim-module</code>, <code>claim-function</code> — название модуля и функции модуля, которые отвечают за форматирование вывода значения ''свойства'' (statement, claim) с учётом квалификаторов, ссылок и прочего. Может, например, дополнительно к основному значению (main snak) вывести значения квалификаторов. Характерные примеры: ** вывод вышестоящих административных единиц и страны в [[Модуль:Wikidata/Places]]; ** вывод авторов латинского названия и даты публикации в [[Модуль:Wikidata/Biology]]; ** вывод операционной системы и даты релиза в [[Модуль:Wikidata/Software]]; ** вывод количества и даты, на которую оно верно, в [[Модуль:Wikidata/number]]; *: Спецификация функции: <code>function p.…( context, options, statement )</code> * <code>value-module</code>, <code>value-function</code> — название модуля и функции модуля, которые отвечают за форматирование ''значения'' (snak, snak data value), в зависимости от контекста, как значений свойства, так и значений квалификатора (если вызывается из <code>claim-module/claim-function</code>). Необходимо для изменения отображения свойства, например, генерации викиссылки вместо простой строки или даже вставки изображения вместо отображения имени файла изображения (так как ссылки на изображения хранятся как строки). Характерные примеры: ** вывод ссылки на [[Викисклад]] в [[Модуль:Wikidata/media]] ** вывод ссылок на внешние сайты в [[Модуль:Wikidata/link]] *: Спецификация функции: <code>function p.…( value, options )</code> === Заготовки функций === {{Скрытый | Заголовок = property-function | Содержание = <syntaxhighlight lang="lua"> function p.formatSomeProperty( context, options ) local claims = context.selectClaims( options, options.property ); if claims == nil then return '' end local formattedStatements = {} for _, claim in ipairs( claims ) do local formattedStatement = context.formatStatement( options, claim ) -- local formattedStatement = p.formatSomeStatement( context, options, claim ) if ( formattedStatement and formattedStatement ~= '' ) then formattedStatement = context.wrapStatement( formattedStatement, options.property, claim.id ) table.insert( formattedStatements, formattedStatement ) end end return mw.text.listToText( formattedStatements, options.separator, options.conjunction ) end </syntaxhighlight> Также см. код метода <code>formatPropertyDefault</code> ниже, в нём присутствует больше проверок и работа параметрами вызова. }} {{Скрытый | Заголовок = claim-function | Содержание = <syntaxhighlight lang="lua"> function formatSomeClaim( context, options, statement ) local circumstances = context.getSourcingCircumstances( statement ); options.qualifiers = statement.qualifiers; local result = context.formatSnak( options, statement.mainsnak, circumstances ); if ( result and result ~= '' and options.references ) then result = result .. context.formatRefs( options, statement ); end return result; end </syntaxhighlight> Также см. код метода <code>formatStatementDefault</code> ниже, в нём есть пример работы с квалификаторами. }} {{Скрытый | Заголовок = value-function | Содержание = <syntaxhighlight lang="lua"> function formatSomeValue( context, options, value ) return value; end </syntaxhighlight> Также см. код метода <code>formatUrlSingle</code> в модуле [[Модуль:URL]]. }} === Context API === {{Заготовка раздела|описать публичные методы, доступные через <code>context</code>.}} ==== Переменные ==== * <code>entity</code> * <code>frame</code> ==== Методы ==== * <code>cloneOptions( options )</code> * <code>getSourcingCircumstances( statement )</code> * <code>formatProperty( options )</code> * <code>formatPropertyDefault( context, options )</code> * <code>formatSnak( options, snak, circumstances )</code> * <code>formatStatement( options, statement )</code> * <code>formatStatementDefault( context, options, statement )</code> * <code>formatRefs( options, statement )</code> * <code>formatValueDefault( context, options, value )</code> * <code>parseTimeBoundariesFromSnak( snak )</code> * <code>parseTimeFromSnak( snak )</code> * <code>selectClaims( options, propertyId )</code> * <code>wrapSnak( value, hash, attributes )</code> * <code>wrapStatement( value, propertyId, claimId, attributes )</code> * <code>wrapQualifier( value, qualifierId, attributes )</code> === Функции для форматирования === ==== property-function ==== * [[Модуль:Wikidata/date|Wikidata/date]]::formatDateIntervalProperty * [[Модуль:Wikidata/Medals|Wikidata/Medals]]::formatProperty * [[Модуль:Wikidata/Software|Wikidata/Software]]::formatVersionProperty * [[Модуль:Wikidata/P512|Wikidata/P512]]::formatAcademicDegree * [[Модуль:Wikidata/number|Wikidata/number]]::formatPropertyWithMostRecentClaimAndIndicator * [[Модуль:Wikidata/number|Wikidata/number]]::formatColorIndex ==== claim-function ==== * [[Модуль:Wikidata/Places|Wikidata/Places]]::formatCountryClaimWithFlag * [[Модуль:Wikidata/Places|Wikidata/Places]]::formatPlaceWithQualifiers * [[Модуль:Wikidata/item|Wikidata/item]]::formatEntityWithGenderClaim * [[Модуль:Wikidata/Biology|Wikidata/Biology]]::formatTaxonNameClaim * [[Модуль:Wikidata/item|Wikidata/item]]::applyDefaultTemplate * [[Модуль:Wikidata/date|Wikidata/date]]::formatDateOfBirthClaim * [[Модуль:Wikidata/date|Wikidata/date]]::formatDateOfDeathClaim ==== value-function ==== * [[Модуль:Wikidata|Wikidata]]::extractCategory * [[Модуль:Wikidata/link|Wikidata/link]]::fromModule * [[Модуль:Wikidata/Medals|Wikidata/Medals]]::formatValue * [[Модуль:Wikidata/media|Wikidata/media]]::formatCommonsCategory * [[Модуль:Wikidata/Software|Wikidata/Software]]::formatExtension * [[Модуль:Wikidata/number|Wikidata/number]]::formatRA * [[Модуль:Wikidata/number|Wikidata/number]]::formatDMS * [[Модуль:Wikidata/url|Wikidata/url]]::formatUrlValue * [[Модуль:Wikidata/url|Wikidata/url]]::formatLangRefs == Тесты == {{Скрытый | Заголовок = [[Модуль:Wikidata/tests]] | Содержание = {{#invoke:Wikidata/tests|run_tests}} }} == См. также == * [[Модуль:Wikibase]] * Независимые иноязычные аналоги: ** [[:fr:Module:Wikidata]] ** [[:ca:Mòdul:Wikidades]] ** [[:it:Modulo:Wikidata]] ** [[:de:Modul:Wikidata]] ** [[:en:Module:WikidataIB]] ** [[:en:Module:Wd]] <noinclude> [[Категория:Модули:Документация]] </noinclude> <includeonly> [[Категория:Модули:Викиданные]] </includeonly> 1e00ff235ce39f7fd8e5927f57fda177a193a7a6 Модуль:Wikidata/tests 828 210 468 2024-07-28T14:14:19Z ruwiki>QBA-bot 0 Защитил страницу [[Модуль:Wikidata/tests]]: критический шаблон или модуль (каскадная защита) ([Редактирование=только автоподтверждённые] (бессрочно) [Переименование=только автоподтверждённые] (бессрочно)) Scribunto text/plain -- Unit tests for [[Module:URL]]. Click talk page to run tests. local p = require( 'Module:UnitTests' ) local wd = require( 'Module:Wikidata' ) local getSnak = function( timeString ) return { datatype = "time", datavalue = { type = "time", value = { after = 0, before = 0, calendarmodel = "http://www.wikidata.org/entity/Q1985727", precision = 11, time = timeString, timezone = 0, }, }, hash = "33bd9a339157ce7b3d74cb10d73bc23529c9a7f3", property = "P585", snaktype = "value", } end function p:test_parseTimeBoundaries() self:equals_deep( '2000-12-31', wd._parseTimeBoundaries( '+2000-12-31T00:00:00Z', 11 ), { 978220800000, 978307199999 } ) self:equals_deep( '2001-01-01', wd._parseTimeBoundaries( '+2001-01-01T00:00:00Z', 11 ), { 978307200000, 978393599999 } ) self:equals_deep( '2001', wd._parseTimeBoundaries( '+2001-00-00T00:00:00Z', 9 ), { 978307200000, 1009843199999 } ) end function p:test_parseTimeFromSnak() self:equals_deep( '2000-12-31', wd._parseTimeFromSnak( getSnak( '+2000-12-31T00:00:00Z' ) ), 978220800000 ) self:equals_deep( '2001-01-01', wd._parseTimeFromSnak( getSnak( '+2001-01-01T00:00:00Z' ) ), 978307200000 ) self:equals_deep( '2001', wd._parseTimeFromSnak( getSnak( '+2001-00-00T00:00:00Z' ) ), 978307200000 ) end return p a49c6e32801a352e27ec0dee7b1af3c93a0f5c10 Шаблон:Docpage 10 178 398 2024-07-29T17:18:37Z ruwiki>Putnik 0 поддержка тёмной темы wikitext text/x-wiki <includeonly>{{#ifeq: {{SUBPAGENAME}} | doc | {{fmbox | class = hlist nowraplinks | style = margin-bottom:1em; background:var(--background-color-progressive-subtle, #eaf3ff); color:inherit; border:1px solid var(--border-color-content-added, #a3d3ff); | image = [[Файл:OOjs UI icon info.svg|24px|link=|alt=|class=skin-invert-image]] | text = <div> * [[:{{#titleparts: {{SUBJECTPAGENAME}} | -1 }}]] * [[:{{SUBJECTPAGENAME}}|Документация]] * [[{{#titleparts: {{TALKPAGENAME}} | -1 }}|Обсуждение]] * [[Служебная:Whatlinkshere/{{#titleparts: {{SUBJECTPAGENAME}} | -1 }}|Где используется]] {{#ifeq: {{NAMESPACE}} | {{ns:Template}} | ** {{Параметры шаблона|{{#titleparts: {{PAGENAME}} | -1 }}}} }}</div><!-- -->{{#if: {{{nocat|}}} || {{#ifexist: {{NAMESPACE}}:{{BASEPAGENAME}} || [[Категория:Шаблоны:Документация несуществующих шаблонов]] }} }} }}{{#if: {{{nocat|}}} || {{#ifeq: {{NAMESPACE}} | Модуль | [[Категория:Модули:Документация]] | [[Категория:Шаблоны:Документация]] }} }} }}</includeonly><noinclude>{{doc}}</noinclude> 9b09d5b771c19e45bd038d248dcf31e500e436ce Шаблон:Родственный проект/styles.css 10 288 737 2024-07-29T20:40:07Z ruwiki>Putnik 0 убрал !important sanitized-css text/css .ts-Родственный_проект, .ts-Родственный_проект.metadata:not(.notheme) { background: var(--background-color-neutral-subtle, #f8f9fa); border: 1px solid var(--border-color-base, #a2a9b1); clear: right; float: right; font-size: 90%; margin: 0 0 1em 1em; padding: .4em; max-width: 19em; width: 19em; line-height: 1.5; } .ts-Родственный_проект th, .ts-Родственный_проект td { padding: .2em 0; vertical-align: middle; } .ts-Родственный_проект th + td { padding-left: .4em; } @media (max-width: 719px) { .ts-Родственный_проект { width: auto; margin-left: 0; margin-right: 0; } } /* [[Категория:Шаблоны:Подстраницы CSS]] */ 50b08ba20d75d9b717bc6920475793f259cd3af1 Шаблон:Рейтинг модуля 10 93 158 2024-07-29T20:44:27Z ruwiki>Putnik 0 поддержка тёмной темы wikitext text/x-wiki {{Module other|{{ombox | type = notice | image = {{#switch: {{{1|}}} | pre-alpha | prealpha | pa | пре-альфа = [[File:Ambox warning blue construction.svg|40x40px|link=]] | alpha | a | альфа = [[File:Greek lc alpha icon.svg|26x26px|link=|class=skin-invert-image]] | beta | b | бета = [[File:Greek lc beta icon.svg|40x40px|link=|class=skin-invert-image]] | release | r | general | g | готов = [[File:Green check.svg|40x40px|link=]] | protected | protect | p | защищен = [[File:Padlock-silver.svg|40x40px|link=]] }} | style = | textstyle = | text = {{#switch: {{{1|}}} | pre-alpha | prealpha | pa | пре-альфа = Этот модуль оценён как [[:Категория:Модули:Пре-альфа версии|пре-альфа-версия]]. Он не закончен и может находиться в разработке. Он не должен использоваться в статьях. Модули остаются в этой стадии до тех пор, пока автор или кто-либо иной не сочтёт их структуру удовлетворительной.<!-- -->{{#switch: {{SUBPAGENAME}}|doc|sandbox=<!-- No category for /doc or /sandbox subpages --> | {{#ifeq: {{{nocat|}}} | true | <!-- No category if user sets nocat=true --> | [[Категория:Модули:Пре-альфа версии]] }} }} | alpha | a | альфа = Этот модуль оценён как [[:Категория:Модули:Альфа-версии|альфа-версия]]. Он готов для тестирований и может быть использован на небольшом количестве страниц для обнаружения проблем. Предложения по изменениям и дополнениям приветствуются.<!-- -->{{#switch: {{SUBPAGENAME}}|doc|sandbox=<!-- No category for /doc or /sandbox subpages --> | {{#ifeq: {{{nocat|}}} | true | <!-- No category if user sets nocat=true --> | [[Категория:Модули:Альфа-версии]] }} }} | beta | b | бета = Этот модуль оценён как [[:Категория:Модули:Бета-версии|бета-версия]]. Он готов для широкого применения, но должен применяться с осторожностью.<!-- -->{{#switch: {{SUBPAGENAME}}|doc|sandbox=<!-- No category for /doc or /sandbox subpages --> | {{#ifeq: {{{nocat|}}} | true | <!-- No category if user sets nocat=true --> | [[Категория:Модули:Бета-версии]] }} }} | release | r | general | g | готов = Этот модуль оценён как [[:Категория:Модули:Стабильные|готовый к использованию]]. Предполагается, что все баги устранены и он готов для широкого использования. Его можно указывать на справочных страницах и рекомендовать к использованию новым участникам. Для его изменения и тестирования, пожалуйста, [[ВП:ТЕСТЫ|используйте песочницу]].<!-- -->{{#switch: {{SUBPAGENAME}}|doc|sandbox=<!-- No category for /doc or /sandbox subpages --> | {{#ifeq: {{{nocat|}}} | true | <!-- No category if user sets nocat=true --> | [[Категория:Модули:Стабильные]] }} }} | protected | protect | p | защищен = Этот модуль относится к [[:Категория:Модули:Критические|критическим]]. У него очень много включений или он используется с подстановкой. Из-за опасности вандализма или ошибочного редактирования он был защищён.<!-- -->{{#switch: {{SUBPAGENAME}}|doc|sandbox=<!-- No category for /doc or /sandbox subpages --> | {{#ifeq: {{{nocat|}}} | true | <!-- No category if user sets nocat=true --> | [[Категория:Модули:Критические]] }} }} | #default = {{error|Рейтинг не указан или указан неправильно.}} }} }}|{{error|Этот шаблон должен использоваться в пространстве модулей.}}|demospace={{{demospace|<noinclude>module</noinclude>}}}}}<noinclude>{{doc}}</noinclude> c3380f20f70295631f2614caead4cbc73c110883 Шаблон:Doc/styles.css 10 173 388 2024-08-05T07:09:06Z ruwiki>Putnik 0 исправление кода для тёмной темы ([[phab:T369874]]) sanitized-css text/css .ts-doc-doc { background-color: var(--background-color-progressive-subtle, #eaf3ff); border: 1px solid var(--border-color-content-added, #afb6e9); clear: both; margin-top: 1em; } /* Ctrl+F ":target" in [[MediaWiki:Common.css]] */ .ts-doc-doc sup.reference:target, .ts-doc-doc ol.references li:target, .ts-doc-doc .highlight-target:target, .ts-doc-doc cite:target, .ts-doc-doc span.citation:target { background: var(--ruwiki-background-color-blue200, #cfe3ff); } .ts-doc-header { align-items: center; background: var(--ruwiki-background-color-blue200, #cfe3ff); display: flex; flex-wrap: wrap; padding: .642857em 1em .5em; overflow: hidden; } .ts-doc-header .ts-tlinks-tlinks { margin-left: auto; } .ts-doc-content { padding: .214286em 1em; } .ts-doc-content:after { content: ''; clear: both; display: block; } .ts-doc-heading { display: inline-block; padding-left: 2em; background: url(//upload.wikimedia.org/wikipedia/commons/c/ca/OOjs_UI_icon_info.svg) center left no-repeat; background-size: contain; font-size: small; min-height: 1.75em; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; } @media screen { html.skin-theme-clientpref-night .ts-doc-heading { background-image: url(//upload.wikimedia.org/wikipedia/commons/c/c0/OOjs_UI_icon_info-invert.svg); } } @media screen and (prefers-color-scheme: dark) { html.skin-theme-clientpref-os .ts-doc-heading { background-image: url(//upload.wikimedia.org/wikipedia/commons/c/c0/OOjs_UI_icon_info-invert.svg); } } .ts-doc-content > *:first-child, .ts-doc-footer > *:first-child { margin-top: .5em; } .ts-doc-content > *:last-child, .ts-doc-footer > *:last-child { margin-bottom: .5em; } .ts-doc-footer { background-color: var(--background-color-progressive-subtle, #eaf3ff); border: 1px solid var(--border-color-content-added, #afb6e9); padding: .214286em 1em; margin-top: .214286em; margin-bottom: .214286em; font-style: italic; } @media (max-width: 719px) { .ts-doc-header { display: block; } .ts-doc-header .ts-tlinks-tlinks { float: none; } } /* [[Категория:Шаблоны:Подстраницы CSS]] */ be8d912472a37a6051bee114da86f913839e7ca0 Модуль:Wikidata 828 262 685 2024-08-07T12:29:07Z ruwiki>Putnik 0 fix Scribunto text/plain ---settings, may differ from project to project local fileDefaultSize = '267x400px' local outputReferences = true local writingSystemElementId = 'Q8209' local langElementId = 'Q7737' ---Ссылки на используемые модули, которые потребуются в 99% случаев загрузки страниц (чтобы иметь на виду при переименовании) local moduleSources = require( 'Module:Sources' ) local WDS = require( 'Module:WikidataSelectors' ) ---Константы ---@type string local CONTENT_LANGUAGE_CODE = mw.language.getContentLanguage():getCode() local p = {} local g_config, g_frame local formatDatavalue, formatEntityId, formatRefs, formatSnak, formatStatement, formatStatementDefault, getSourcingCircumstances, getPropertyParams ---@param obj table ---@param target table ---@param skipEmpty boolean | nil ---@return table local function copyTo( obj, target, skipEmpty ) for key, val in pairs( obj ) do if skipEmpty ~= true or ( val ~= nil and val ~= '' ) then target[ key ] = val end end return target end ---@param prev number | nil ---@param next number | nil ---@return number | nil local function min( prev, next ) if prev == nil or prev > next then return next end return prev end ---@param prev number | nil ---@param next number | nil ---@return number | nil local function max( prev, next ) if prev == nil or prev < next then return next end return prev end ---@param section string ---@param code string ---@return any | nil local function getConfig( section, code ) if g_config == nil then g_config = require( 'Module:Wikidata/config' ) end if not g_config then g_config = {} end if not section then return g_config end if not code then return g_config[ section ] or {} end if not g_config[ section ] then return nil end return g_config[ section ][ code ] end ---@param code string ---@param sortKey string | nil ---@return string local function getCategoryByCode( code, sortKey ) local value = getConfig( 'categories', code ) if not value or value == '' then return '' end if sortKey ~= nil then return '[[Category:' .. value .. '|' .. sortKey .. ']]'; -- экранировать? else return '[[Category:' .. value .. ']]' end end ---@param isoStr string | table ---@return table | nil local function splitISO8601( isoStr ) if 'table' == type( isoStr ) then if isoStr.args and isoStr.args[ 1 ] then isoStr = '' .. isoStr.args[ 1 ] else return 'unknown argument type: ' .. type( isoStr ) .. ': ' .. table.tostring( isoStr ) end end local Y, M, D = ( function( str ) local pattern = "(%-?%d+)%-(%d+)%-(%d+)T" local _Y, _M, _D = mw.ustring.match( str, pattern ) return tonumber( _Y ), tonumber( _M ), tonumber( _D ) end )( isoStr ) local h, m, s = ( function( str ) local pattern = "T(%d+):(%d+):(%d+)%Z" local _H, _M, _S = mw.ustring.match( str, pattern ) return tonumber( _H ), tonumber( _M ), tonumber( _S ) end )( isoStr ) local oh, om = ( function( str ) if str:sub(-1) == "Z" then -- ends with Z, Zulu time return 0, 0 end -- matches ±hh:mm, ±hhmm or ±hh; else returns nils local pattern = "([-+])(%d%d):?(%d?%d?)$" local sign, oh, om = mw.ustring.match( str, pattern ) sign, oh, om = sign or "+", oh or "00", om or "00" return tonumber( sign .. oh ), tonumber( sign .. om ) end )( isoStr ) return { year=Y, month=M, day=D, hour=( h + oh ), min=( m + om ), sec=s } end ---Внутренняя функции для получения границ временного диапазона ---@param time string ---@param precision number ---@return table | nil function p._parseTimeBoundaries( time, precision ) local s = splitISO8601( time ) if not s then return nil end if precision >= 0 and precision <= 8 then local powers = { 1000000000 , 100000000, 10000000, 1000000, 100000, 10000, 1000, 100, 10 } local power = powers[ precision + 1 ] local left = s.year - ( s.year % power ) return { tonumber( os.time( { year=left, month=1, day=1, hour=0, min=0, sec=0 } ) ) * 1000, tonumber( os.time( { year=left + power - 1, month=12, day=31, hour=29, min=59, sec=58 } ) ) * 1000 + 1999 } end if precision == 9 then return { tonumber( os.time( { year=s.year, month=1, day=1, hour=0, min=0, sec=0} )) * 1000, tonumber( os.time( { year=s.year, month=12, day=31, hour=23, min=59, sec=58} )) * 1000 + 1999 } end if precision == 10 then local lastDays = { 31, 28.25, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } local lastDay = lastDays[ s.month ] return { tonumber( os.time( { year=s.year, month=s.month, day=1, hour=0, min=0, sec=0 } ) ) * 1000, tonumber( os.time( { year=s.year, month=s.month, day=lastDay, hour=23, min=59, sec=58 } ) ) * 1000 + 1999 } end if precision == 11 then return { tonumber( os.time( { year=s.year, month=s.month, day=s.day, hour=0, min=0, sec=0 } ) ) * 1000, tonumber( os.time( { year=s.year, month=s.month, day=s.day, hour=23, min=59, sec=58 } ) ) * 1000 + 1999 } end if precision == 12 then return { tonumber( os.time( { year=s.year, month=s.month, day=s.day, hour=s.hour, min=0, sec=0 } ) ) * 1000, tonumber( os.time( { year=s.year, month=s.month, day=s.day, hour=s.hour, min=59, sec=58 } ) ) * 1000 + 1999 } end if precision == 13 then return { tonumber( os.time( { year=s.year, month=s.month, day=s.day, hour=s.hour, min=s.min, sec=0 } ) ) * 1000, tonumber( os.time( { year=s.year, month=s.month, day=s.day, hour=s.hour, min=s.min, sec=58 } ) ) * 1000 + 1999 } end if precision == 14 then local t = tonumber( os.time( { year=s.year, month=s.month, day=s.day, hour=s.hour, min=s.min, sec=0 } ) ) return { t * 1000, t * 1000 + 999 } end error( 'Unsupported precision: ' .. precision ) end ---Внутренняя функция для получения числового значения времени из snak'а ---@param table snak ---@return number | nil function p._parseTimeFromSnak( snak ) if snak and snak.datavalue and snak.datavalue.value and snak.datavalue.value.time then local timeData = splitISO8601( tostring( snak.datavalue.value.time ) ) timeData.month = math.max( timeData.month, 1 ) timeData.day = math.max( timeData.day, 1 ) return tonumber( os.time( timeData ) ) * 1000 end return nil end ---Функция для формирования категории на основе wikidata/config ---@param options table ---@param entityId string ---@return string local function extractCategory( options, entityId ) if not entityId or not options.category or options.nocat then return '' end if type( entityId ) ~= 'string' then entityId = entityId.id end local claims = WDS.load( entityId, options.category ) if not claims then return '' end for _, claim in pairs( claims ) do if claim and claim.mainsnak and claim.mainsnak.datavalue and claim.mainsnak.datavalue.type == 'wikibase-entityid' then local catEntityId = claim.mainsnak.datavalue.value.id local wbStatus, catSiteLink = pcall( mw.wikibase.getSitelink, catEntityId ) if wbStatus and catSiteLink then return '[[' .. catSiteLink .. ']]' end end end return '' end ---Преобразует строку в булевое значение ---@param valueToParse string ---@return boolean Преобразованное значение, если его удалось распознать, или defaultValue во всех остальных случаях local function toBoolean( valueToParse, defaultValue ) if valueToParse ~= nil then if valueToParse == false or valueToParse == '' or valueToParse == 'false' or valueToParse == '0' then return false end return true end return defaultValue end ---Обрачивает отформатированное значение в инлайновый или блочный тег. ---@param value string value ---@param attributes table of attributes ---@return string HTML tag with value local function wrapValue( value, attributes ) local tagName = 'span' local spacer = '' if string.match( value, '\n' ) or string.match( value, '<t[dhr][ >]' ) or string.match( value, '<div[ >]' ) or string.find( value, 'UNIQ%-%-imagemap' ) then tagName = 'div' spacer = '\n' end local attrString = '' for key, val in pairs( attributes or {} ) do local _key = mw.text.trim( key ) local _value = mw.text.encode( mw.text.trim( val ) ) attrString = attrString .. _key .. '="' .. _value .. '" ' end return '<' .. tagName .. ' ' .. attrString .. '>' .. spacer .. value .. '</' .. tagName .. '>' end ---Wraps formatted snak value into HTML tag with attributes. ---@param value string value of snak ---@param hash string ---@param attributes table of extra attributes ---@return string HTML tag with value local function wrapSnak( value, hash, attributes ) local newAttributes = mw.clone( attributes or {} ) newAttributes[ 'class' ] = ( newAttributes[ 'class' ] or '' ) .. ' wikidata-snak' if hash then newAttributes[ 'data-wikidata-hash'] = hash else newAttributes[ 'class' ] = newAttributes[ 'class' ] .. ' wikidata-main-snak' end return wrapValue( value, newAttributes ) end ---Wraps formatted statement value into HTML tag with attributes. ---@param value string value of statement ---@param propertyId string PID of property ---@param claimId string ID of claim or nil for local value ---@param attributes table of extra attributes ---@return string HTML tag with value local function wrapStatement( value, propertyId, claimId, attributes ) local newAttributes = mw.clone( attributes or {} ) newAttributes[ 'class' ] = newAttributes[ 'class' ] or '' newAttributes[ 'data-wikidata-property-id' ] = string.upper( propertyId ) if claimId then newAttributes[ 'class' ] = newAttributes[ 'class' ] .. ' wikidata-claim' newAttributes[ 'data-wikidata-claim-id' ] = claimId else newAttributes[ 'class' ] = newAttributes[ 'class' ] .. ' no-wikidata' end return wrapValue( value, newAttributes ) end ---Wraps formatted qualifier's statement value into HTML tag with attributes. ---@param value string value of qualifier's statement ---@param qualifierId string PID of qualifier ---@param attributes table of extra attributes ---@return string HTML tag with value local function wrapQualifier( value, qualifierId, attributes ) local newAttributes = mw.clone( attributes or {} ) newAttributes[ 'data-wikidata-qualifier-id' ] = string.upper( qualifierId ) return wrapValue( value, newAttributes ) end ---Функция для получения сущности (еntity) для текущей страницы ---Подробнее о сущностях см. d:Wikidata:Glossary/ru ---@param id string Идентификатор (типа P18, Q42) ---@return table Таблица, элементы которой индексируются с нуля local function getEntityFromId( id ) local entity local wbStatus if id then wbStatus, entity = pcall( mw.wikibase.getEntity, id ) else wbStatus, entity = pcall( mw.wikibase.getEntity ) end return entity end ---Внутренняя функция для формирования сообщения об ошибке ---@param key string Ключ элемента в таблице config.errors (например entity-not-found) ---@return void local function throwError( key ) error( getConfig( 'errors', key ) ) end ---Функция для получения идентификатора сущностей ---@param value table ---@return string local function getEntityIdFromValue( value ) local prefix = '' if value[ 'entity-type' ] == 'item' then prefix = 'Q' elseif value[ 'entity-type' ] == 'property' then prefix = 'P' else throwError( 'unknown-entity-type' ) end return prefix .. value[ 'numeric-id' ] end ---Проверка на наличие специализированной функции в опциях ---@param options table ---@param prefix string ---@return function local function getUserFunction( options, prefix, defaultFunction ) -- проверка на указание специализированных обработчиков в параметрах, -- переданных при вызове if options[ prefix .. '-module' ] or options[ prefix .. '-function' ] then -- проверка на пустые строки в параметрах или их отсутствие if not options[ prefix .. '-module' ] or not options[ prefix .. '-function' ] then throwError( 'unknown-' .. prefix .. '-module' ) end -- динамическая загруза модуля с обработчиком указанным в параметре local formatter = require( 'Module:' .. options[ prefix .. '-module' ] ) if formatter == nil then throwError( prefix .. '-module-not-found' ) end local fun = formatter[ options[ prefix .. '-function' ] ] if fun == nil then throwError( prefix .. '-function-not-found' ) end return fun end return defaultFunction end ---Выбирает свойства по property id, дополнительно фильтруя их по рангу ---@param context table ---@param options table ---@param propertySelector string ---@return table | nil local function selectClaims( context, options, propertySelector ) if not context then error( 'context not specified' ); end if not options then error( 'options not specified' ); end if not options.entityId then error( 'options.entity is missing' ); end if not propertySelector then error( 'propertySelector not specified' ); end local result = WDS.load( options.entityId, propertySelector ) if not result or #result == 0 then return nil end if options.limit and options.limit ~= '' and options.limit ~= '-' then local limit = tonumber( options.limit, 10 ) while #result > limit do table.remove( result ) end end return result end ---Функция для получения значения свойства элемента в заданный момент времени. ---@param entityId string ---@param boundaries table Временные границы ---@param propertyIds table<string> ---@param selectors table<string> ---@return table Таблица соответствующих значений свойства local function getPropertyInBoundaries( context, entityId, boundaries, propertyIds, selectors ) if type( entityId ) ~= 'string' then error( 'type of entityId argument expected string, but was ' .. type(entityId)); end local results = {} if not propertyIds or #propertyIds == 0 then return results end for i, propertyId in ipairs( propertyIds ) do local selector if selectors ~= nil then selector = selectors[ i ] or selectors[ propertyId ] or propertyId else selector = propertyId end local fakeAllClaims = {} fakeAllClaims[ propertyId ] = mw.wikibase.getAllStatements( entityId, propertyId ) local filteredClaims = WDS.filter( fakeAllClaims, selector .. '[rank:preferred, rank:normal]' ) if filteredClaims then for _, claim in pairs( filteredClaims ) do if not boundaries then if not claim.qualifiers or not claim.qualifiers.P582 then table.insert( results, claim.mainsnak ) end else local startBoundaries = p.getTimeBoundariesFromQualifier( context.frame, context, claim, 'P580' ) local endBoundaries = p.getTimeBoundariesFromQualifier( context.frame, context, claim, 'P582' ) if ( startBoundaries == nil or startBoundaries[ 1 ] <= boundaries[ 1 ] ) and ( endBoundaries == nil or endBoundaries[ 1 ] >= boundaries[ 2 ] ) then table.insert( results, claim.mainsnak ) end end end end if #results > 0 then break end end return results end ---@param context table ---@param propertyId string ---@return table | nil function p.getTimeBoundariesFromProperty( context, propertyId ) local dateClaims = WDS.filter( context.entity.claims, propertyId ) if not dateClaims or #dateClaims == 0 then return nil; end -- only support exact date so far, but need improvment local left = nil local right = nil for _, claim in pairs( dateClaims ) do if not claim.mainsnak then return nil end local boundaries = context.parseTimeBoundariesFromSnak( claim.mainsnak ) if not boundaries then return nil end left = min( left, boundaries[ 1 ] ) right = max( right, boundaries[ 2 ] ) end if not left or not right then return nil end return { left, right } end ---@param context table ---@param propertyIds table<string> ---@return table | nil function p.getTimeBoundariesFromProperties( context, propertyIds ) for _, propertyId in ipairs( propertyIds ) do local result = p.getTimeBoundariesFromProperty( context, propertyId ); if result then return result end end return nil end ---@param context table ---@param statement table ---@param qualifierId string ---@return table | nil function p.getTimeBoundariesFromQualifier( _, context, statement, qualifierId ) -- only support exact date so far, but need improvement local left, right if statement.qualifiers and statement.qualifiers[ qualifierId ] then for _, qualifier in pairs( statement.qualifiers[ qualifierId ] ) do local boundaries = context.parseTimeBoundariesFromSnak( qualifier ) if not boundaries then return nil end left = min( left, boundaries[ 1 ] ) right = max( right, boundaries[ 2 ] ) end end if not left or not right then return nil end return { left, right } end ---@param _ table ---@param context table ---@param statement table ---@param qualifierIds table<string> ---@return table | nil function p.getTimeBoundariesFromQualifiers( _, context, statement, qualifierIds ) if not qualifierIds then qualifierIds = { 'P582', 'P580', 'P585' } end for _, qualifierId in pairs( qualifierIds ) do local result = p.getTimeBoundariesFromQualifier( _, context, statement, qualifierId ) if result then return result end end return nil end ---@type table<string> local getLabelWithLang_DEFAULT_PROPERTIES = { 'P1813', 'P1448', 'P1705' } ---@type table<string> local getLabelWithLang_DEFAULT_SELECTORS = { 'P1813[language:' .. CONTENT_LANGUAGE_CODE .. '][!P282,P282:' .. writingSystemElementId .. '][!P3831,P3831:Q105690470]', 'P1448[language:' .. CONTENT_LANGUAGE_CODE .. '][!P282,P282:' .. writingSystemElementId .. '][!P3831,P3831:Q105690470]', 'P1705[language:' .. CONTENT_LANGUAGE_CODE .. '][!P282,P282:' .. writingSystemElementId .. '][!P3831,P3831:Q105690470]' } ---Функция для получения метки элемента в заданный момент времени. ---@param context table ---@param options table ---@param entityId string ---@param boundaries table ---@param propertyIds table ---@param selectors table<string> ---@return string, string Текстовая метка элемента, язык метки local function getLabelWithLang( context, options, entityId, boundaries, propertyIds, selectors ) if type( entityId ) ~= 'string' then error( 'type of entityId argument expected string, but was ' .. type( entityId ) ); end if not entityId then return nil end local langCode = CONTENT_LANGUAGE_CODE -- name from label local label if options.text and options.text ~= '' then label = options.text else if not propertyIds then propertyIds = getLabelWithLang_DEFAULT_PROPERTIES selectors = getLabelWithLang_DEFAULT_SELECTORS end -- name from properties local results = getPropertyInBoundaries( context, entityId, boundaries, propertyIds, selectors ) for _, result in pairs( results ) do if result.datavalue and result.datavalue.value then if result.datavalue.type == 'monolingualtext' and result.datavalue.value.text then label = result.datavalue.value.text langCode = result.datavalue.value.language break elseif result.datavalue.type == 'string' then label = result.datavalue.value break end end end if not label then label, langCode = mw.wikibase.getLabelWithLang( entityId ) if not langCode then return nil end end end return label, langCode end ---@param context table ---@param options table ---@return string local function formatPropertyDefault( context, options ) if not context then error( 'context not specified' ); end if not options then error( 'options not specified' ); end if not options.entityId then error( 'options.entityId missing' ); end local claims if options.property then -- TODO: Почему тут может не быть property? if options.rank then -- передать настройки ранга из конфига claims = context.selectClaims( options, options.property .. options.rank ) else claims = context.selectClaims( options, options.property ) end end if claims == nil then return '' --TODO error? end -- Обход всех заявлений утверждения и с накоплением оформленных предпочтительных -- заявлений в таблице local formattedClaims = {} for _, claim in pairs( claims ) do local formattedStatement = context.formatStatement( options, claim ) -- здесь может вернуться либо оформленный текст заявления, либо строка ошибки, либо nil if formattedStatement and formattedStatement ~= '' then if not options.plain then formattedStatement = context.wrapStatement( formattedStatement, options.property, claim.id ) end table.insert( formattedClaims, formattedStatement ) end end -- создание текстовой строки со списком оформленых заявлений из таблицы local out = mw.text.listToText( formattedClaims, options.separator, options.conjunction ) if out ~= '' then if options.before then out = options.before .. out end if options.after then out = out .. options.after end end return out end ---Create context ---@param initOptions table ---@return table | nil local function initContext( initOptions ) local context = { entityId = initOptions.entityId, entity = initOptions.entity, extractCategory = extractCategory, formatSnak = formatSnak, formatPropertyDefault = formatPropertyDefault, formatStatementDefault = formatStatementDefault, getPropertyInBoundaries = getPropertyInBoundaries, getTimeBoundariesFromProperty = p.getTimeBoundariesFromProperty, getTimeBoundariesFromProperties = p.getTimeBoundariesFromProperties, getTimeBoundariesFromQualifier = p.getTimeBoundariesFromQualifier, getTimeBoundariesFromQualifiers = p.getTimeBoundariesFromQualifiers, parseTimeFromSnak = p._parseTimeFromSnak, getLabelWithLang = getLabelWithLang, wrapSnak = wrapSnak, wrapStatement = wrapStatement, wrapQualifier = wrapQualifier, } context.cloneOptions = function( options ) local entity = options.entity options.entity = nil local newOptions = mw.clone( options ) options.entity = entity newOptions.entity = entity newOptions.frame = options.frame; -- На склонированном фрейме frame:expandTemplate() return newOptions end context.formatProperty = function( options ) local func = getUserFunction( options, 'property', context.formatPropertyDefault ) return func( context, options ) end context.formatStatement = function( options, statement ) return formatStatement( context, options, statement ) end context.formatSnak = function( options, snak, circumstances ) return formatSnak( context, options, snak, circumstances ) end context.formatRefs = function( options, statement ) return formatRefs( context, options, statement ) end context.parseTimeBoundariesFromSnak = function( snak ) if snak and snak.datavalue and snak.datavalue.value and snak.datavalue.value.time and snak.datavalue.value.precision then return p._parseTimeBoundaries( snak.datavalue.value.time, snak.datavalue.value.precision ) end return nil end context.getSourcingCircumstances = function( statement ) return getSourcingCircumstances( statement ) end context.selectClaims = function( options, propertyId ) return selectClaims( context, options, propertyId ) end return context end ---Функция для оформления утверждений (statement) ---Подробнее о утверждениях см. d:Wikidata:Glossary/ru ---@param options table ---@return string Formatted wikitext. local function formatProperty( options ) -- Получение сущности по идентификатору local entity = getEntityFromId( options.entityId ) if not entity then return -- throwError( 'entity-not-found' ) end -- проверка на присутсвие у сущности заявлений (claim) -- подробнее о заявлениях см. d:Викиданные:Глоссарий if not entity.claims then return '' --TODO error? end -- improve options options.frame = g_frame options.entity = entity options.extends = function( self, newOptions ) return copyTo( newOptions, copyTo( self, {} ) ) end if options.i18n then options.i18n = copyTo( options.i18n, copyTo( getConfig( 'i18n' ), {} ) ) else options.i18n = getConfig( 'i18n' ) end local context = initContext( options ) return context.formatProperty( options ) end ---Функция для оформления одного утверждения (statement) ---@param context table ---@param options table ---@param statement table ---@return string Formatted wikitext. function formatStatement( context, options, statement ) if not statement then error( 'statement is not specified or nil' ) end if not statement.type or statement.type ~= 'statement' then throwError( 'unknown-claim-type' ) end local functionToCall = getUserFunction( options, 'claim', context.formatStatementDefault ) return functionToCall( context, options, statement ) end ---@param statement table ---@return table function getSourcingCircumstances( statement ) if not statement then error( 'statement is not specified' ) end local circumstances = {} if statement.qualifiers and statement.qualifiers.P1480 then for _, qualifier in pairs( statement.qualifiers.P1480 ) do if qualifier and qualifier.datavalue and qualifier.datavalue.type == 'wikibase-entityid' and qualifier.datavalue.value and qualifier.datavalue.value[ 'entity-type'] == 'item' then table.insert( circumstances, qualifier.datavalue.value.id ) end end end return circumstances end ---Функция для оформления одного утверждения (statement) ---@param context table Context. ---@param options table Parameters. ---@param statement table ---@return string Formatted wikitext. function formatStatementDefault( context, options, statement ) if not context then error( 'context is not specified' ) end if not options then error( 'options is not specified' ) end if not statement then error( 'statement is not specified' ) end local circumstances = context.getSourcingCircumstances( statement ) options.qualifiers = statement.qualifiers local result = context.formatSnak( options, statement.mainsnak, circumstances ) if options.qualifier and statement.qualifiers and statement.qualifiers[ options.qualifier ] then local qualifierConfig = getPropertyParams( options.qualifier, nil, {} ) if options.i18n then qualifierConfig.i18n = options.i18n end if qualifierConfig.datatype == 'time' then qualifierConfig.nolinks = true end local qualifierValues = {} for _, qualifierSnak in pairs( statement.qualifiers[ options.qualifier ] ) do local snakValue = context.formatSnak( qualifierConfig, qualifierSnak ) if snakValue and snakValue ~= '' then table.insert( qualifierValues, snakValue ) end end if result and result ~= '' and #qualifierValues then if qualifierConfig.invisible then result = result .. table.concat( qualifierValues, ', ' ) else result = result .. ' (' .. table.concat( qualifierValues, ', ' ) .. ')' end end end if result and result ~= '' and options.references then result = result .. context.formatRefs( options, statement ) end return result end ---Функция для оформления части утверждения (snak) ---Подробнее о snak см. d:Викиданные:Глоссарий ---@param context table Context. ---@param options table Parameters. ---@param snak table ---@param circumstances table ---@return string Formatted wikitext. function formatSnak( context, options, snak, circumstances ) circumstances = circumstances or {} local result if snak.snaktype == 'somevalue' then if options[ 'somevalue' ] and options[ 'somevalue' ] ~= '' then result = options[ 'somevalue' ] else result = options.i18n[ 'somevalue' ] end elseif snak.snaktype == 'novalue' then if options[ 'novalue' ] and options[ 'novalue' ] ~= '' then result = options[ 'novalue' ] else result = options.i18n[ 'novalue' ] end elseif snak.snaktype == 'value' then result = formatDatavalue( context, options, snak.datavalue, snak.datatype ) for _, item in pairs( circumstances ) do if options.i18n[ item ] then result = options.i18n[ item ] .. result end end else throwError( 'unknown-snak-type' ) end if not result or result == '' then return nil end if options.plain then return result end return context.wrapSnak( result, snak.hash ) end ---Функция для оформления объектов-значений с географическими координатами ---@param value string Raw value. ---@param options table Parameters. ---@return string Formatted string. local function formatGlobeCoordinate( value, options ) -- проверка на требование в параметрах вызова на возврат сырого значения if options[ 'subvalue' ] == 'latitude' then -- широты return value[ 'latitude' ] elseif options[ 'subvalue' ] == 'longitude' then -- долготы return value[ 'longitude' ] elseif options[ 'nocoord' ] and options[ 'nocoord' ] ~= '' then -- если передан параметр nocoord, то не выводить координаты -- обычно это делается при использовании нескольких карточек на странице return '' else -- в противном случае формируются параметры для вызова шаблона {{coord}} -- нужно дописать в документации шаблона, что он отсюда вызывается, и что -- любое изменние его парамеров должно быть согласовано с кодом тут local coordModule = require( 'Module:Coordinates' ) local globe = options.globe or '' if globe == '' and value[ 'globe' ] then local globes = require( 'Module:Wikidata/Globes' ) globe = globes[ value[ 'globe' ] ] or '' end local display = 'inline' if options.display and options.display ~= '' then display = options.display elseif ( options.property:upper() == 'P625' ) then display = 'title' end local format = options.format or '' if format == '' then format = 'dms' if value[ 'precision' ] then local precision = value[ 'precision' ] * 60 if precision >= 60 then format = 'd' elseif precision >= 1 then format = 'dm' end end end g_frame.args = { tostring( value[ 'latitude' ] ), tostring( value[ 'longitude' ] ), globe = globe, type = options.type and options.type or '', scale = options.scale and options.scale or '', display = display, format = format, } return coordModule.coord(g_frame) end end ---Функция для оформления объектов-значений с файлами с Викисклада ---@param value string Raw value. ---@param options table Parameters. ---@return string Formatted string. local function formatCommonsMedia( value, options ) local image = value local caption = '' if options[ 'caption' ] and options[ 'caption' ] ~= '' then caption = options[ 'caption' ] end if caption ~= '' then caption = wrapQualifier( caption, 'P2096', { class = 'media-caption', style = 'display:block' } ) end if not string.find( value, '[%[%]%{%}]' ) and not string.find( value, 'UNIQ%-%-imagemap' ) then -- если в value не содержится викикод или imagemap, то викифицируем имя файла -- ищем слово imagemap в строке, потому что вставляется плейсхолдер: [[phab:T28213]] image = '[[File:' .. value .. '|frameless' if options[ 'border' ] and options[ 'border' ] ~= '' then image = image .. '|border' end local size = options[ 'size' ] if size and size ~= '' then -- TODO: check localized pixel names too if not string.match( size, 'px$' ) then size = size .. 'px' end else size = fileDefaultSize end image = image .. '|' .. size if options[ 'alt' ] and options[ 'alt' ] ~= '' then image = image .. '|alt=' .. options[ 'alt' ] end if caption ~= '' then image = image .. '|' .. caption end image = image .. ']]' if caption ~= '' then image = image .. '<br>' .. caption end else image = image .. caption .. getCategoryByCode( 'media-contains-markup' ) end return image end ---Function for render math formulas ---@param value string Value. ---@param options table Parameters. ---@return string Formatted string. local function formatMath( value, options ) return options.frame:extensionTag{ name = 'math', content = value } end ---Функция для оформления внешних идентификаторов ---@param value string ---@param options table ---@return string local function formatExternalId( value, options ) local formatter = options.formatter local propertyId = options.property:upper() if not formatter or formatter == '' then local isGoodFormat = false local wbStatus, formatRegexStatements = pcall( mw.wikibase.getBestStatements, propertyId, 'P1793' ) if wbStatus and formatRegexStatements then for _, statement in pairs( formatRegexStatements ) do if statement.mainsnak.snaktype == 'value' then local pattern = mw.ustring.gsub( statement.mainsnak.datavalue.value, '\\', '%' ) pattern = mw.ustring.gsub( pattern, '{%d+,?%d*}', '+' ) if ( string.find( pattern, '|' ) or string.find( pattern, '%)%?' ) or mw.ustring.match( value, '^' .. pattern .. '$' ) ~= nil ) then isGoodFormat = true break end end end end if isGoodFormat then local formatterStatements wbStatus, formatterStatements = pcall( mw.wikibase.getBestStatements, propertyId, 'P1630' ) if wbStatus and formatterStatements then for _, statement in pairs( formatterStatements ) do if statement.mainsnak.snaktype == 'value' then formatter = statement.mainsnak.datavalue.value break end end end end end if formatter and formatter ~= '' then local encodedValue = mw.ustring.gsub( value, '%%', '%%%%' ) -- ломается, если подставить внутрь другого mw.ustring.gsub local link = mw.ustring.gsub( mw.ustring.gsub( formatter, '$1', encodedValue ), '.', { [ ' ' ] = '%20', [ '+' ] = '%2b', [ '[' ] = '%5B', [ ']' ] = '%5D' } ) local title = options.title if not title or title == '' then title = '$1' end title = mw.ustring.gsub( mw.ustring.gsub( title, '$1', encodedValue ), '.', { [ '[' ] = '(', [ ']' ] = ')' } ) return '[' .. link .. ' ' .. title .. ']' end return value end ---Функция для оформления числовых значений ---@param value table Объект-значение ---@param options table Таблица параметров ---@return string Оформленный текст local function formatQuantity( value, options ) -- диапазон значений local amount = string.gsub( value.amount, '^%+', '' ) local lang = mw.language.getContentLanguage() local langCode = lang:getCode() local function formatNum( number, sigfig ) local multiplier = '' if options.countByThousands then local powers = options.i18n.thousandPowers local pos = 1 while math.abs( number ) >= 1000 and pos < #powers do number = number / 1000 pos = pos + 1 end multiplier = powers[ pos ] if math.abs( number ) >= 100 then sigfig = sigfig or 0 elseif math.abs( number ) >= 10 then sigfig = sigfig or 1 else sigfig = sigfig or 2 end else sigfig = sigfig or 12 -- округление до 12 знаков после запятой, на 13-м возникает ошибка в точности end local iMultiplier = 10^sigfig number = math.floor( number * iMultiplier + 0.5 ) / iMultiplier return string.gsub( lang:formatNum( number ), '^-', '−' ) .. multiplier end local out = formatNum( tonumber( amount ) ) if value.upperBound then local diff = tonumber( value.upperBound ) - tonumber( amount ) if diff > 0 then -- временная провека, пока у большинства значений не будет убрано ±0 -- Пробуем понять до какого знака округлять local integer, dot, decimals, _ = value.upperBound:match( '^+?-?(%d*)(%.?)(%d*)(.*)' ) local precision if dot == '' then precision = -integer:match( '0*$' ):len() else precision = #decimals end local bound = formatNum( diff, precision ) if string.match( bound, 'E%-(%d+)' ) then -- если в экспоненциальном формате local digits = tonumber( string.match( bound, 'E%-(%d+)' ) ) - 2 bound = formatNum( diff * 10 ^ digits, precision ) bound = string.sub( bound, 0, 2 ) .. string.rep( '0', digits ) .. string.sub( bound, -string.len( bound ) + 2 ) end out = out .. ' ± ' .. bound end end if options.unit and options.unit ~= '' then if options.unit ~= '-' then out = out .. ' ' .. options.unit end elseif value.unit and string.match( value.unit, 'http://www.wikidata.org/entity/' ) then local unitEntityId = string.gsub( value.unit, 'http://www.wikidata.org/entity/', '' ) if unitEntityId ~= 'undefined' then local wbStatus, unitEntity = pcall( mw.wikibase.getEntity, unitEntityId ) if wbStatus == true and unitEntity then if unitEntity.claims.P2370 and unitEntity.claims.P2370[ 1 ].mainsnak.snaktype == 'value' and not value.upperBound and options.siConversion == true then local conversionToSiUnit = string.gsub( unitEntity.claims.P2370[ 1 ].mainsnak.datavalue.value.amount, '^%+', '' ) if math.floor( math.log10( conversionToSiUnit ) ) ~= math.log10( conversionToSiUnit ) then -- Если не степени десятки (переводить сантиметры в метры не надо!) local outValue = tonumber( amount ) * conversionToSiUnit if outValue > 0 then -- Пробуем понять до какого знака округлять local integer, dot, decimals, _ = amount:match( '^(%d*)(%.?)(%d*)(.*)' ) local precision if dot == '' then precision = -integer:match( '0*$' ):len() else precision = #decimals end local adjust = math.log10( math.abs( conversionToSiUnit ) ) + math.log10( 2 ) local minPrecision = 1 - math.floor( math.log10( outValue ) + 2e-14 ) out = formatNum( outValue, math.max( math.floor( precision + adjust ), minPrecision ) ) else out = formatNum( outValue, 0 ) end unitEntityId = string.gsub( unitEntity.claims.P2370[ 1 ].mainsnak.datavalue.value.unit, 'http://www.wikidata.org/entity/', '' ) wbStatus, unitEntity = pcall( mw.wikibase.getEntity, unitEntityId ) end end local label = getLabelWithLang( context, options, unitEntity.id, nil, { "P5061", "P558", "P558" }, { 'P5061[language:' .. langCode .. ']', 'P558[P282:' .. writingSystemElementId .. ', P407:' .. langElementId .. ']', 'P558[!P282][!P407]' } ) out = out .. ' ' .. label end end end return out end ---Функция для оформления URL ---@param context table ---@param options table ---@param value string local function formatUrlValue( context, options, value ) if not options.length or options.length == '' then options.length = 25 end local moduleUrl = require( 'Module:URL' ) return moduleUrl.formatUrlSingle( context, options, value ) end local DATATYPE_CACHE = {} ---Get property datatype by ID. ---@param propertyId string Property ID, e.g. 'P123'. ---@return string Property datatype, e.g. 'commonsMedia', 'time' or 'url'. local function getPropertyDatatype( propertyId ) if not propertyId or not string.match( propertyId, '^P%d+$' ) then return nil end local cached = DATATYPE_CACHE[ propertyId ] if cached ~= nil then return cached end local wbStatus, propertyEntity = pcall( mw.wikibase.getEntity, propertyId ) if wbStatus ~= true or not propertyEntity then return nil end mw.log("Loaded datatype " .. propertyEntity.datatype .. " of " .. propertyId .. ' from wikidata, consider passing datatype argument to formatProperty call or to Wikidata/config' ) DATATYPE_CACHE[ propertyId ] = propertyEntity.datatype return propertyEntity.datatype end ---@param datavalue table ---@return function local function getPlainValueFunction( datavalue, _ ) if datavalue.type == 'wikibase-entityid' then return function( _, _, value ) return getEntityIdFromValue( value ) end elseif datavalue.type == 'string' then return function( _, _, value ) return value end elseif datavalue.type == 'monolingualtext' then return function( _, _, value ) return value.text end elseif datavalue.type == 'globecoordinate' then return function( _, _, value ) return value.latitude .. ',' .. value.longitude end elseif datavalue.type == 'quantity' then return function( _, _, value ) return value.amount end elseif datavalue.type == 'time' then return function( _, _, value ) return value.time end end throwError( 'unknown-datavalue-type' ) end ---@param datavalue table ---@param datatype string ---@return function local function getDefaultValueFunction( datavalue, datatype ) -- вызов обработчиков по умолчанию для известных типов значений if datavalue.type == 'wikibase-entityid' then -- Entity ID return function( context, options, value ) return formatEntityId( context, options, getEntityIdFromValue( value ) ) end elseif datavalue.type == 'string' then -- String if datatype and datatype == 'commonsMedia' then -- Media return function( _, options, value ) return formatCommonsMedia( value, options ) end elseif datatype and datatype == 'external-id' then -- External ID return function( _, options, value ) return formatExternalId( value, options ) end elseif datatype and datatype == 'math' then -- Math formula return function( _, options, value ) return formatMath( value, options ) end elseif datatype and datatype == 'url' then -- URL return formatUrlValue end return function( _, _, value ) return value end elseif datavalue.type == 'monolingualtext' then -- моноязычный текст (строка с указанием языка) return function( _, options, value ) if options.monolingualLangTemplate == 'lang' then if value.language == CONTENT_LANGUAGE_CODE then return value.text end return options.frame:expandTemplate{ title = 'lang-' .. value.language, args = { value.text } } elseif options.monolingualLangTemplate == 'ref' then return '<span class="lang" lang="' .. value.language .. '">' .. value.text .. '</span>' .. options.frame:expandTemplate{ title = 'ref-' .. value.language } else return '<span class="lang" lang="' .. value.language .. '">' .. value.text .. '</span>' end end elseif datavalue.type == 'globecoordinate' then -- географические координаты return function( _, options, value ) return formatGlobeCoordinate( value, options ) end elseif datavalue.type == 'quantity' then return function( _, options, value ) return formatQuantity( value, options ) end elseif datavalue.type == 'time' then return function( context, options, value ) local moduleDate = require( 'Module:Wikidata/date' ) return moduleDate.formatDate( context, options, value ) end end -- во всех стальных случаях возвращаем ошибку throwError( 'unknown-datavalue-type' ) end ---Функция для оформления значений (value) ---Подробнее о значениях см. d:Wikidata:Glossary/ru ---@param context table ---@param options table ---@param datavalue table ---@param datatype string ---@return string Оформленный текст function formatDatavalue( context, options, datavalue, datatype ) if not context then error( 'context not specified' ); end if not options then error( 'options not specified' ); end if not datavalue then error( 'datavalue not specified' ); end if not datavalue.value then error( 'datavalue.value is missing' ); end -- проверка на указание специализированных обработчиков в параметрах, -- переданных при вызове if options.plain then context.formatValueDefault = getPlainValueFunction( datavalue, datatype ) else context.formatValueDefault = getDefaultValueFunction( datavalue, datatype ) end local functionToCall = getUserFunction( options, 'value', context.formatValueDefault ) return functionToCall( context, options, datavalue.value ) end local DEFAULT_BOUNDARIES = { os.time() * 1000, os.time() * 1000} ---Функция для оформления идентификатора сущности ---@param context table ---@param options table ---@param entityId string ---@return string Оформленный текст function formatEntityId( context, options, entityId ) -- получение локализованного названия local boundaries if options.qualifiers then boundaries = p.getTimeBoundariesFromQualifiers( context.frame, context, { qualifiers = options.qualifiers } ) end if not boundaries then boundaries = DEFAULT_BOUNDARIES end local label, labelLanguageCode = getLabelWithLang( context, options, entityId, boundaries ) -- определение соответствующей показываемому элементу категории local category = context.extractCategory( options, { id = entityId } ) -- получение ссылки по идентификатору local link = mw.wikibase.sitelink( entityId ) if link then -- ссылка на категорию, а не добавление страницы в неё if mw.ustring.match( link, '^' .. mw.site.namespaces[ 14 ].name .. ':' ) then link = ':' .. link end if label and not options.rawArticle then if labelLanguageCode ~= CONTENT_LANGUAGE_CODE then label = '<span lang="' .. label .. '">' .. label .. '</span>' end local a = '[[' .. link .. '|' .. label .. ']]' if CONTENT_LANGUAGE_CODE ~= labelLanguageCode and 'mul' ~= labelLanguageCode then a = a .. getCategoryByCode( 'links-to-entities-with-missing-local-language-label' ) end return a .. category else return '[[' .. link .. ']]' .. category end end if label then -- TODO: возможно, лучше просто mw.wikibase.getLabel(entityId) -- красная ссылка -- TODO: разобраться, почему не всегда есть options.frame local moduleRedLink = require( 'Module:Wikidata/redLink' ) local title = mw.title.new( label ) if title and not title.exists and options.frame then local rawLabel = mw.wikibase.getLabel(entityId) or label -- без |text= и boundaries; or label - костыль local redLink = moduleRedLink.formatRedLinkWithInfobox(rawLabel, label, entityId) if CONTENT_LANGUAGE_CODE ~= labelLanguageCode and 'mul' ~= labelLanguageCode then redLink = '<span lang="' .. labelLanguageCode .. '">' .. redLink .. '</span>' .. getCategoryByCode( 'links-to-entities-with-missing-local-language-label' ) end return redLink .. category end -- TODO: перенести до проверки на существование статьи local addWdLink = false if ( not options.format or options.format ~= 'text' ) and entityId ~= 'Q6581072' and entityId ~= 'Q6581097' -- TODO: переписать на format=text then addWdLink = true end -- одноимённая статья уже существует - выводится текст и ссылка на ВД return moduleRedLink.formatText(label, entityId, addWdLink) .. category end -- сообщение об отсутвии локализованного названия -- not good, but better than nothing return '[[:d:' .. entityId .. '|' .. entityId .. ']]<span style="border-bottom: 1px dotted; cursor: help; white-space: nowrap" title="В Викиданных нет русской подписи к элементу. Вы можете помочь, указав русский вариант подписи.">?</span>' .. getCategoryByCode( 'links-to-entities-with-missing-label' ) .. category end ---Функция для оформления утверждений (statement) ---Подробнее о утверждениях см. d:Wikidata:Glossary/ru ---@deprecated Use p.formatProperty() instead ---@param frame table ---@return string Строка оформленного текста, предназначенная для отображения в статье function p.formatStatements( frame ) return p.formatProperty( frame ) end ---Получение параметров, которые обычно используются для вывода свойства. ---@param propertyId string ---@param datatype string ---@param params table function getPropertyParams( propertyId, datatype, params ) local config = getConfig() -- Различные уровни настройки параметров, по убыванию приоритета local propertyParams = {} -- 1. Параметры, указанные явно при вызове if params then for key, value in pairs( params ) do if value ~= '' then propertyParams[ key ] = value end end end if toBoolean( propertyParams.plain, false ) then propertyParams.separator = propertyParams.separator or ', ' propertyParams.conjunction = propertyParams.conjunction or ', ' else -- 2. Настройки конкретного параметра if config.properties and config.properties[ propertyId ] then for key, value in pairs( config.properties[ propertyId ] ) do if propertyParams[ key ] == nil then propertyParams[ key ] = value end end end -- 3. Указанный пресет настроек if propertyParams.preset and config.presets and config.presets[ propertyParams.preset ] then for key, value in pairs( config.presets[ propertyParams.preset ] ) do if propertyParams[ key ] == nil then propertyParams[ key ] = value end end end datatype = datatype or params.datatype or propertyParams.datatype or getPropertyDatatype( propertyId ) if propertyParams.datatype == nil then propertyParams.datatype = datatype end -- 4. Настройки для типа данных if datatype and config.datatypes and config.datatypes[ datatype ] then for key, value in pairs( config.datatypes[ datatype ] ) do if propertyParams[ key ] == nil then propertyParams[ key ] = value end end end -- 5. Общие настройки для всех свойств if config.global then for key, value in pairs( config.global ) do if propertyParams[ key ] == nil then propertyParams[ key ] = value end end end end return propertyParams end ---Функция для оформления утверждений (statement) ---Подробнее о утверждениях см. d:Wikidata:Glossary/ru ---@param frame table ---@return string Строка оформленного текста, предназначенная для отображения в статье function p.formatProperty( frame ) local args = copyTo( frame.args, {} ) -- проверка на отсутствие обязательного параметра property if not args.property then throwError( 'property-param-not-provided' ) end local override local propertyId = mw.language.getContentLanguage():ucfirst( string.gsub( args.property, '([^Pp0-9].*)$', function(w) if string.sub( w, 1, 1 ) == '~' then override = w end return '' end ) ) if override then args[ override:match( '[,~]([^=]*)=' ) ] = override:match( '=(.*)' ) args.property = propertyId end -- проброс всех параметров из шаблона {wikidata} и параметра from откуда угодно local p_frame = frame while p_frame do if p_frame:getTitle() == mw.site.namespaces[ 10 ].name .. ':Wikidata' then copyTo( p_frame.args, args, true ) end if p_frame.args and p_frame.args.from and p_frame.args.from ~= '' then args.entityId = p_frame.args.from else args.entityId = mw.wikibase.getEntityIdForCurrentPage() end p_frame = p_frame:getParent() end args = getPropertyParams( propertyId, nil, args ) local datatype = args.datatype -- перевод итоговых значений флагов в true/false и добавление значений -- по умолчанию только в том случае, если они нигде не были указаны ранее args.plain = toBoolean( args.plain, false ) args.nocat = not args.plain and toBoolean( args.nocat, false ) args.references = not args.plain and toBoolean( args.references, true ) -- если значение передано в параметрах вызова то выводим только его if args.value and args.value ~= '' then -- специальное значение для скрытия Викиданных if args.value == '-' then return '' end local value = args.value -- опция, запрещающая оформление значения, поэтому никак не трогаем if args.plain then return value end local context = initContext( args ) -- обработчики по типу значения local wrapperExtraArgs = {} if args[ 'value-module' ] and args[ 'value-function' ] and not string.find( value, '[%[%]%{%}]' ) then local func = getUserFunction( args, 'value' ) value = func( context, args, value ) elseif datatype == 'commonsMedia' then value = formatCommonsMedia( value, args ) elseif datatype == 'external-id' and not string.find( value, '[%[%]%{%}]' ) then wrapperExtraArgs[ 'data-wikidata-external-id' ] = mw.text.killMarkers( value ) value = formatExternalId( value, args ) --elseif datatype == 'math' then -- args.frame = frame -- костыль: в formatMath нужно frame:extensionTag -- value = formatMath( value, args ) elseif datatype == 'url' then value = formatUrlValue( context, args, value ) end -- оборачиваем в тег для JS-функций if string.match( propertyId, '^P%d+$' ) then value = mw.text.trim( value ) -- временная штрафная категория для исправления табличных вставок local allowTables = getPropertyParams( propertyId, nil, {} ).allowTables if not allowTables and string.match( value, '<t[dhr][ >]' ) -- and not string.match( value, '<table[ >]' ) -- and not string.match( value, '^%{%|' ) then value = value .. getCategoryByCode( 'value-contains-table', propertyId ) else value = wrapStatement( value, propertyId, nil, wrapperExtraArgs ) end end return value end -- ability to disable loading Wikidata if args.entityId == '-' then return '' end g_frame = frame -- после проверки всех аргументов -- вызов функции оформления для свойства (набора утверждений) return formatProperty( args ) end ---Функция проверки на присутствие источника в списке нерекомендованных. ---@param snaks table ---@return boolean local function isReferenceDeprecated( snaks ) if not snaks then return false end if snaks.P248 and snaks.P248[ 1 ] and snaks.P248[ 1 ].datavalue and snaks.P248[ 1 ].datavalue.value.id then local entityId = snaks.P248[ 1 ].datavalue.value.id if getConfig( 'deprecatedSources', entityId ) then return true end elseif snaks.P1433 and snaks.P1433[ 1 ] and snaks.P1433[ 1 ].datavalue and snaks.P1433[ 1 ].datavalue.value.id then local entityId = snaks.P1433[ 1 ].datavalue.value.id if getConfig( 'deprecatedSources', entityId ) then return true end end return false end ---Функция оформления ссылок на источники (reference) ---Подробнее о ссылках на источники см. d:Wikidata:Glossary/ru --- ---Экспортируется в качестве зарезервированной точки для вызова из функций-расширения вида claim-module/claim-function через context ---Вызов из других модулей напрямую осуществляться не должен (используйте frame:expandTemplate вместе с одним из специлизированных шаблонов вывода значения свойства). ---@param context table ---@param options table ---@param statement table ---@return string Оформленные примечания для отображения в статье function formatRefs( context, options, statement ) if not context then error( 'context not specified' ); end if not options then error( 'options not specified' ); end if not options.entityId then error( 'options.entityId missing' ); end if not statement then error( 'statement not specified' ); end if not outputReferences then return '' end ---@type string[] local references = {} if statement.references then local hasNotDeprecated = false local displayCount = 0 for _, reference in pairs( statement.references ) do if not isReferenceDeprecated( reference.snaks ) then hasNotDeprecated = true end end for _, reference in pairs( statement.references ) do local display = true if hasNotDeprecated then if isReferenceDeprecated( reference.snaks ) then display = false end end if displayCount >= 2 then if options.entityId and options.property then local propertyId = mw.ustring.match( options.property, '^[Pp][0-9]+' ) -- TODO: обрабатывать не тут, а раньше local moreReferences = '<sup>[[d:' .. options.entityId .. '#' .. string.upper( propertyId ) .. '|[…]]]</sup>' table.insert( references, moreReferences ) end break end if display == true then ---@type string local refText = moduleSources.renderReference( g_frame, options.entityId, reference ) if refText and refText ~= '' then table.insert( references, refText ) displayCount = displayCount + 1 end end end end return table.concat( references ) end return p 4558f762f30c6ebfb9f5333dbd7ebda83c6873f2 Заглавная страница 0 1 1 2024-08-07T16:07:23Z MediaWiki default 1 Добро пожаловать в Miraheze! wikitext text/x-wiki __NOTOC__ == Добро пожаловать в {{SITENAME}}! == Эта главная страница была создана автоматически и, похоже, ещё не заменена. === Для бюрократа(-ов) этой вики === Здравствуйте и добро пожаловать на вашу новую вики! Благодарим Вас за выбор Miraheze в качестве хостинга, и мы надеемся, что вы будете пользоваться нашими услугами. Вы можете сразу же начать работать над вашем вики-сайтов, как только пожелаете. Нужна помощь? Нет проблем! Мы поможем вам с вашей вики по мере необходимости. Для того, чтобы начать, мы добавили несколько ссылок о работе с MediaWiki: * [[mw:Special:MyLanguage/Help:Contents|Обсуждение руководства MediaWiki (например, навигация, редактирование, удаление страниц, блокирование пользователей)]] * [[meta:Special:MyLanguage/FAQ|ЧЗВ по Miraheze]] * [[meta:Special:MyLanguage/Request features|Запрос изменений настроек вашей вики.]] (Изменения расширений, оформления и логотипа/фавикона должны выполняться через [[Special:ManageWiki]] в вашей вики, см. [[meta:Special:MyLanguage/ManageWiki|ManageWiki]] для получения дополнительной информации.) ==== Но, Miraheze, я всё ещё не понимаю X! ==== Что ж, это не проблема. Даже если что-то не описано в документации/ЧЗВ, мы всё равно будем рады помочь вам. Вы можете найти нас здесь: * [[meta:Special:MyLanguage/Help center|На нашем собственном Miraheze вики]] * На [[phorge:|Phorge]] * На нашем [https://miraheze.org/discord Discord-сервере] * На IRC в #miraheze в irc.libera.chat (irc.libera.chat ([irc://irc.libera.chat/%23miraheze direct link]; [https://web.libera.chat/?channel=#miraheze вебчат])) === Для посетителя этой вики === Здравствуйте, заглавная страница по умолчанию ещё не была заменена бюрократом(-ами) этой вики. Возможно, администрация этого сайта разрабатывает эту страницу, поэтому мы рекомендуем вам зайти чуть позже. da708791005da529f6c1fffe139a9b3660d023e2 12 1 2024-08-07T17:48:49Z DuOfOrl 5 Защитил страницу [[Заглавная страница]]: популярная страница ([Редактирование=Разрешено только администраторам] (бессрочно) [Переименование=Разрешено только администраторам] (бессрочно)) wikitext text/x-wiki __NOTOC__ == Добро пожаловать в {{SITENAME}}! == Эта главная страница была создана автоматически и, похоже, ещё не заменена. === Для бюрократа(-ов) этой вики === Здравствуйте и добро пожаловать на вашу новую вики! Благодарим Вас за выбор Miraheze в качестве хостинга, и мы надеемся, что вы будете пользоваться нашими услугами. Вы можете сразу же начать работать над вашем вики-сайтов, как только пожелаете. Нужна помощь? Нет проблем! Мы поможем вам с вашей вики по мере необходимости. Для того, чтобы начать, мы добавили несколько ссылок о работе с MediaWiki: * [[mw:Special:MyLanguage/Help:Contents|Обсуждение руководства MediaWiki (например, навигация, редактирование, удаление страниц, блокирование пользователей)]] * [[meta:Special:MyLanguage/FAQ|ЧЗВ по Miraheze]] * [[meta:Special:MyLanguage/Request features|Запрос изменений настроек вашей вики.]] (Изменения расширений, оформления и логотипа/фавикона должны выполняться через [[Special:ManageWiki]] в вашей вики, см. [[meta:Special:MyLanguage/ManageWiki|ManageWiki]] для получения дополнительной информации.) ==== Но, Miraheze, я всё ещё не понимаю X! ==== Что ж, это не проблема. Даже если что-то не описано в документации/ЧЗВ, мы всё равно будем рады помочь вам. Вы можете найти нас здесь: * [[meta:Special:MyLanguage/Help center|На нашем собственном Miraheze вики]] * На [[phorge:|Phorge]] * На нашем [https://miraheze.org/discord Discord-сервере] * На IRC в #miraheze в irc.libera.chat (irc.libera.chat ([irc://irc.libera.chat/%23miraheze direct link]; [https://web.libera.chat/?channel=#miraheze вебчат])) === Для посетителя этой вики === Здравствуйте, заглавная страница по умолчанию ещё не была заменена бюрократом(-ами) этой вики. Возможно, администрация этого сайта разрабатывает эту страницу, поэтому мы рекомендуем вам зайти чуть позже. da708791005da529f6c1fffe139a9b3660d023e2 24 12 2024-08-07T19:38:25Z DuOfOrl 5 Содержимое страницы заменено на «__NOTOC__ == Добро пожаловать в Мемнотацию! == {{Заглавная/Шапка}}» wikitext text/x-wiki __NOTOC__ == Добро пожаловать в Мемнотацию! == {{Заглавная/Шапка}} a8912afb15aae163f13fdf2d00a073d790456b46 Участник:DuOfOrl 2 2 2 2024-08-07T16:51:15Z DuOfOrl 5 Новая страница: «MC Гей да нет да нет (играет гимн Ксеноморфии на электрооргане)» wikitext text/x-wiki MC Гей да нет да нет (играет гимн Ксеноморфии на электрооргане) 18e6c33c25c1077c6d40bf450350c8e5182fbd4f Участник:Ксеноморф 2 3 3 2024-08-07T16:52:28Z Ксеноморф 2 Новая страница: «Ну тип создатель этого эээ да уничтожим всех врагов Ксеноморфии слава Ксеноморфии» wikitext text/x-wiki Ну тип создатель этого эээ да уничтожим всех врагов Ксеноморфии слава Ксеноморфии ac12e2fdee9713b6f2586c714ef7bd4d1f4a6234 4 3 2024-08-07T16:52:42Z Ксеноморф 2 wikitext text/x-wiki Ну тип создатель этого вики эээ да уничтожим всех врагов Ксеноморфии слава Ксеноморфии 3c284ed9ea37e4df70fa0c998db3597e7fce87cb Файл:MemnotationLogo.png 6 5 6 2024-08-07T17:28:38Z Ксеноморф 2 Сделан Афонтовианом wikitext text/x-wiki == Краткое описание == Сделан Афонтовианом 063760b12b36ca743f38b960e8ce615c9f77b07e 7 6 2024-08-07T17:38:41Z Ксеноморф 2 Ксеноморф загрузил новую версию [[Файл:MemnotationLogo.png]] wikitext text/x-wiki == Краткое описание == Сделан Афонтовианом 063760b12b36ca743f38b960e8ce615c9f77b07e 8 7 2024-08-07T17:39:30Z Ксеноморф 2 Ксеноморф загрузил новую версию [[Файл:MemnotationLogo.png]] wikitext text/x-wiki == Краткое описание == Сделан Афонтовианом 063760b12b36ca743f38b960e8ce615c9f77b07e 9 8 2024-08-07T17:40:16Z Ксеноморф 2 Ксеноморф загрузил новую версию [[Файл:MemnotationLogo.png]] wikitext text/x-wiki == Краткое описание == Сделан Афонтовианом 063760b12b36ca743f38b960e8ce615c9f77b07e 10 9 2024-08-07T17:41:56Z Ксеноморф 2 Ксеноморф загрузил новую версию [[Файл:MemnotationLogo.png]] wikitext text/x-wiki == Краткое описание == Сделан Афонтовианом 063760b12b36ca743f38b960e8ce615c9f77b07e 11 10 2024-08-07T17:44:34Z Ксеноморф 2 Ксеноморф загрузил новую версию [[Файл:MemnotationLogo.png]] wikitext text/x-wiki == Краткое описание == Сделан Афонтовианом 063760b12b36ca743f38b960e8ce615c9f77b07e Шаблон:Заглавная/Шапка 10 6 14 13 2024-08-07T18:17:06Z DuOfOrl 5 1 версия импортирована: Экспортировано из Русской Википедии (https://ru.wikipedia.org/wiki/%D0%A8%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD:%D0%97%D0%B0%D0%B3%D0%BB%D0%B0%D0%B2%D0%BD%D0%B0%D1%8F/%D0%A8%D0%B0%D0%BF%D0%BA%D0%B0) wikitext text/x-wiki <noinclude><templatestyles src="Шаблон:Заглавная/styles.css" /></noinclude> <templatestyles src="Шаблон:Заглавная/Шапка/styles.css" /> <div class="main-block main-top"> <div class="main-top-left"> <h1 class="main-top-header">Добро пожаловать в&nbsp;[[Википедия|Википедию]],</h1> [[Свободный контент|свободную энциклопедию]], которую [[Справка:Введение в Википедию|может редактировать каждый]]. <div class="main-top-mobileSearch"><span class="main-top-mobileSearchButton skin-minerva-search-trigger">[[Special:Search|Искать среди {{NUMBEROFARTICLES}} {{plural:{{NUMBEROFARTICLES}}|статьи|статей}}]]</span></div> </div> <div class="main-top-right main-plainlist"> <p class="main-top-articleCount">Сейчас в&nbsp;Википедии '''[[Special:Statistics|{{NUMBEROFARTICLES}} {{plural:{{NUMBEROFARTICLES}}|статья|статьи|статей}}]]''' на&nbsp;[[Русский язык|русском&nbsp;языке]].</p> <ul> <li class="main-top-createArticle">{{Заглавная/Кнопка|Википедия:Мастер статей|Создать статью}}</li> <li>{{Заглавная/Кнопка|Википедия:Справка|Справка|class=mw-ui-quiet}}</li> <li>{{Заглавная/Кнопка|Портал:Обзор|Порталы|class=mw-ui-quiet}}</li> </ul> </div> </div><noinclude> [[Категория:Шаблоны:Подстраницы шаблонов|Заглавная]] [[Категория:Шаблоны, используемые на Заглавной странице]] </noinclude> 824063451cf8a6bfd68477221e98b721c54adfe9 23 14 2024-08-07T19:36:43Z DuOfOrl 5 wikitext text/x-wiki <noinclude><templatestyles src="Шаблон:Заглавная/styles.css" /></noinclude> <templatestyles src="Шаблон:Заглавная/Шапка/styles.css" /> <div class="main-block main-top"> <h1 class="main-top-header"> [[Файл:MemnotationLogo.png]]</h1> <div class="main-top-left"> <h1 class="main-top-header">Добро пожаловать в&nbsp;[[Мемнотация|Мемнотацию]],</h1> свободную энциклопедию, затрагивающую тему Мемного мира, дискорд-государств и прочего. <div class="main-top-mobileSearch"><span class="main-top-mobileSearchButton skin-minerva-search-trigger">[[Special:Search|Искать среди {{NUMBEROFARTICLES}} {{plural:{{NUMBEROFARTICLES}}|статьи|статей}}]]</span></div> </div> <div class="main-top-right main-plainlist"> <p class="main-top-articleCount">Сейчас в&nbsp;Мемнотации '''[[Special:Statistics|{{NUMBEROFARTICLES}} {{plural:{{NUMBEROFARTICLES}}|статья|статьи|статей}}]]'''.</p> </div><noinclude> [[Категория:Шаблоны:Подстраницы шаблонов|Заглавная]] [[Категория:Шаблоны, используемые на Заглавной странице]] </noinclude> ff19767d497e881c8d6f34f43e14ed773a5597da Шаблон:Заглавная/styles.css 10 8 19 18 2024-08-07T18:23:17Z DuOfOrl 5 1 версия импортирована: Экспортировано из Русской Википедии sanitized-css text/css /* Новое оформление [[Заглавная страница]] Главный референс: https://design.wikimedia.org/style-guide/ https://github.com/wikimedia/wikimedia-ui-base/blob/master/wikimedia-ui-base.less Не удаляйте код до завершения работы */ /* Стандартные заголовки */ .main-header.main-header.main-header { border-bottom-color: transparent; margin-bottom: 0.25em; margin-top: 0; padding-bottom: 0; padding-top: 0; } body.skin-minerva .main-block h1, body.skin-minerva .main-block h2 { /* хак для Минервы в связи с [[mw:Heading HTML changes]] */ display: block; } body.skin-timeless .main-header.main-header.main-header { border-bottom-color: transparent; } /* Списки без оформления */ .main-plainlist ul { list-style: none; margin: 0; padding: 0; } .main-plainlist li { margin-bottom: 0; } /* Убираем нумерацию заголовков, создаваемую опцией «Автоматически нумеровать заголовки» на [[Служебная:Настройки#mw-prefsection-rendering]] */ .main-block .mw-headline-number { display: none; } /* Скопировано из [[:w:Template:Screen reader-only/styles.css]] */ .main-block .sr-only { border: 0; clip: rect(0, 0, 0, 0); /* Removed from CSS specification */ /* clip-path is the replacement for clip, but very few browsers support it. */ clip-path: polygon(0px 0px, 0px 0px, 0px 0px); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; white-space: nowrap; } /* Планшеты */ @media (min-width: 720px) { .main-wikimedia { padding-left: 1rem; padding-right: 1rem; } } /* Стационарные компьютеры */ @media (min-width: 1000px) { .main-wrapper { display: flex; gap: 1.5rem; /* Fixes https://phabricator.wikimedia.org/F54943102 */ flex-wrap: wrap; } .main-wrapper-column { flex: 1; } .main-wikimedia { padding-left: 1.5rem; padding-right: 1.5rem; } } /* [[Категория:Шаблоны:Подстраницы CSS]] */ 22963811044f787be151a02e4e09cbdc96d990d3 21 19 2024-08-07T19:18:12Z DuOfOrl 5 sanitized-css text/css /* Новое оформление [[Заглавная страница]] Главный референс: https://design.wikimedia.org/style-guide/ https://github.com/wikimedia/wikimedia-ui-base/blob/master/wikimedia-ui-base.less Не удаляйте код до завершения работы */ /* Стандартные заголовки */ .main-header.main-header.main-header { border-bottom-color: transparent; margin-bottom: 0.25em; margin-top: 0; padding-bottom: 0; padding-top: 0; } body.skin-timeless .main-header.main-header.main-header { border-bottom-color: transparent; } /* Списки без оформления */ .main-plainlist > ul { list-style: none; margin: 0; padding: 0; } .main-plainlist li { margin-bottom: 0; } /* Убираем нумерацию заголовков, создаваемую опцией «Автоматически нумеровать заголовки» на [[Служебная:Настройки#mw-prefsection-rendering]] */ .main-block .mw-headline-number { display: none; } /* Скопировано из [[:w:Template:Screen reader-only/styles.css]] */ .main-block .sr-only { border: 0; clip: rect(0, 0, 0, 0); /* Removed from CSS specification */ /* clip-path is the replacement for clip, but very few browsers support it. */ clip-path: polygon(0px 0px, 0px 0px, 0px 0px); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; white-space: nowrap; } /* Планшеты */ @media (min-width: 720px) { .main-wikimedia { padding-top: 1rem; padding-left: 1rem; padding-right: 1rem; } } /* Стационарные компьютеры */ @media (min-width: 1000px) { .main-wrapper { display: flex; margin: 0 -0.75rem; } .main-wrapper-column { flex: 1; margin: 0 0.75rem; } .main-wikimedia { padding-top: 1.5rem; padding-left: 1.5rem; padding-right: 1.5rem; } } /* [[Категория:Шаблоны:Подстраницы CSS]] */ d9380aba4391612dd1da0942c05b2d2808b0d483 Шаблон:Заглавная/Шапка/styles.css 10 9 20 2024-08-07T18:24:16Z DuOfOrl 5 Новая страница: «/* Новое оформление [[Заглавная страница]] Главный референс: https://design.wikimedia.org/style-guide/ https://github.com/wikimedia/wikimedia-ui-base/blob/master/wikimedia-ui-base.less Не удаляйте код до завершения работы */ /* Стандартные заголовки */ .main-header.main-header.main-header { border-bottom-color: transparent; margin-bottom: 0.25em; margin-to...» sanitized-css text/css /* Новое оформление [[Заглавная страница]] Главный референс: https://design.wikimedia.org/style-guide/ https://github.com/wikimedia/wikimedia-ui-base/blob/master/wikimedia-ui-base.less Не удаляйте код до завершения работы */ /* Стандартные заголовки */ .main-header.main-header.main-header { border-bottom-color: transparent; margin-bottom: 0.25em; margin-top: 0; padding-bottom: 0; padding-top: 0; } body.skin-minerva .main-block h1, body.skin-minerva .main-block h2 { /* хак для Минервы в связи с [[mw:Heading HTML changes]] */ display: block; } body.skin-timeless .main-header.main-header.main-header { border-bottom-color: transparent; } /* Списки без оформления */ .main-plainlist ul { list-style: none; margin: 0; padding: 0; } .main-plainlist li { margin-bottom: 0; } /* Убираем нумерацию заголовков, создаваемую опцией «Автоматически нумеровать заголовки» на [[Служебная:Настройки#mw-prefsection-rendering]] */ .main-block .mw-headline-number { display: none; } /* Скопировано из [[:w:Template:Screen reader-only/styles.css]] */ .main-block .sr-only { border: 0; clip: rect(0, 0, 0, 0); /* Removed from CSS specification */ /* clip-path is the replacement for clip, but very few browsers support it. */ clip-path: polygon(0px 0px, 0px 0px, 0px 0px); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; white-space: nowrap; } /* Планшеты */ @media (min-width: 720px) { .main-wikimedia { padding-left: 1rem; padding-right: 1rem; } } /* Стационарные компьютеры */ @media (min-width: 1000px) { .main-wrapper { display: flex; gap: 1.5rem; /* Fixes https://phabricator.wikimedia.org/F54943102 */ flex-wrap: wrap; } .main-wrapper-column { flex: 1; } .main-wikimedia { padding-left: 1.5rem; padding-right: 1.5rem; } } /* [[Категория:Шаблоны:Подстраницы CSS]] */ 22963811044f787be151a02e4e09cbdc96d990d3 22 20 2024-08-07T19:34:29Z DuOfOrl 5 sanitized-css text/css /* Новое оформление шаблона [[Шаблон:Заглавная/Шапка]] Основано на: https://github.com/wikimedia/wikimedia-ui-base/blob/master/wikimedia-ui-base.less https://design.wikimedia.org/style-guide/ */ .main-top { clear: both; margin-top: 1rem; padding-bottom: 1.5rem; } .main-top-left { font-size: 1rem; } .main-top-left > p { font-size: 0.875em; margin: 0.5em 0 0; padding: 0; } body.skin-vector .main-top-left > p, body.skin-minerva .main-top-left > p, body.skin-timeless .main-top-left > p { margin: 0; } .main-top-right { margin-top: 0.5em; } .main-top-right > ul { display: none; margin-top: 0.5rem; } .main-top-header { border-bottom: 0; margin: 0; padding: 0; } body.skin-monobook .main-top-header { line-height: 1; } .main-top-articleCount { margin: 0; padding: 0; } body.skin-minerva .main-top-articleCount { display: none; } .main-top-mobileSearch { display: none; margin-top: 1rem; } body.skin-minerva .main-top-mobileSearch { display: block; } body.skin-minerva .main-top-mobileSearch .main-top-mobileSearchButton a { background: #fff; border: none; box-shadow: 0 2px 2px 0 rgba( 0, 0, 0, 0.25 ); color: #72777d; display: block; font-weight: normal; padding: 0.25em 0.85em; text-decoration: none; text-align: left; } /* Планшеты */ @media (min-width: 720px) { .main-top { background-color: #f8f9fa; border: 1px solid #c8ccd1; border-radius: 2px; box-shadow: 0 1px 1px rgba(0, 0, 0, .15); margin-bottom: 1rem; padding: 1rem; } .main-top-right > ul { display: flex; flex-wrap: wrap; } .main-top-articleCount { margin-bottom: 0.5rem; } body.skin-minerva .main-top-articleCount { display: block; } body.skin-minerva .main-top-mobileSearch { display: none; } } /* Стационарные компьютеры */ @media (min-width: 1000px) { .main-top { align-items: center; background-image: url(https://upload.wikimedia.org/wikipedia/commons/e/e3/Wikipedia_logo_letters_banner.svg); background-position: right; background-repeat: no-repeat; display: flex; margin-bottom: 1.5rem; margin-top: 0.5rem; padding-bottom: 0; padding-left: 0; padding-top: 0; } .main-top-left { background-image: linear-gradient(to right, #f8f9fa 0%, #f8f9fa 70%, rgba(248, 249, 250, 0) 100%); flex: 2.5; padding: 2rem 0 2rem 1rem; } .main-top-right { flex: 2; margin-top: 0; text-align: right; } .main-top-right > ul { align-items: center; flex-direction: row-reverse; gap: 0.5em; justify-content: right; margin-top: 0; text-align: left; } } /* Широкие стационарные компьютеры */ @media (min-width: 1280px) { .main-top { padding-right: 1.5rem; } body.skin-minerva .main-top, body.skin-vector-2022 .main-top { padding-right: 1rem; } .main-top-left { padding-left: 1.5rem; } body.skin-minerva .main-top-left, body.skin-vector-2022 .main-top-left { padding-left: 1rem; } } /* [[Категория:Шаблоны:Подстраницы CSS]] */ d58309b538c16843c1518ff7efa497f562e036ea Шаблон:Документировать 10 18 36 2024-08-08T15:54:53Z DuOfOrl 5 Новая страница: «{{ombox |type = content |text = '''Этому {{#ifeq: {{NAMESPACE}} | Модуль | модулю | шаблону }} не хватает [[Проект:Технические работы/Шаблоны/Документирование|документации]].''' |text-small = Вы можете помочь проекту, {{big|'''{{SUBJECTSPACE}}:{{PAGENAME:{{{1|{{SUBJECTPAGENAME}}/doc}}}}}|создав описание {{#ifeq: {{NAMESP...» wikitext text/x-wiki {{ombox |type = content |text = '''Этому {{#ifeq: {{NAMESPACE}} | Модуль | модулю | шаблону }} не хватает [[Проект:Технические работы/Шаблоны/Документирование|документации]].''' |text-small = Вы можете помочь проекту, {{big|'''[[{{SUBJECTSPACE}}:{{PAGENAME:{{{1|{{SUBJECTPAGENAME}}/doc}}}}}|создав описание {{#ifeq: {{NAMESPACE}} | Модуль | модуля | шаблона }}]]'''}}: что он делает, как его использовать, какие параметры он принимает, в какие категории добавляет. Это поможет другим использовать его. * Не забывайте про [[Проект:Технические работы/Шаблоны/Категоризация|категории]] ({{#ifeq: {{NAMESPACE}} | Модуль || на странице /doc&#32; }}их нужно оборачивать в {{tag|includeonly}}) и интервики. * Некоторые советы по оформлению есть на странице проекта «[[Проект:Технические работы/Шаблоны/Документирование|Документирование шаблонов]]». }}<includeonly>{{#if: {{{nocat|}}}{{#ifeq: {{PAGENAME}} | {{SUBPAGENAME}} || {{#ifeq: {{SUBPAGENAME}} | песочница | nocat }} }} || {{#switch: {{NAMESPACE}} | {{ns:10}} = [[Категория:Шаблоны:Недокументированные]] | {{ns:828}} = {{#ifeq:{{ROOTPAGENAME}}|Песочница||[[Категория:Модули:Недокументированные]]}} }} }}</includeonly><noinclude> {{doc-inline}} Данное сообщение появляется при отсутствующей странице документации, включаемой шаблоном {{t|doc}}. {{doc-end}} [[Категория:Шаблоны:Предупреждения]] [[Категория:Шаблоны:Для документирования шаблонов]] </noinclude> 7779e82507cacf3a1c77cdb878dd6efafd76b3ce Шаблон:Doc-end 10 19 37 2024-08-08T15:56:09Z DuOfOrl 5 Новая страница: «<includeonly></div> </div><templatestyles src="Шаблон:Doc/styles.css" />{{#ifexpr: {{NAMESPACENUMBER}} mod 2 = 1 <!-- Например, [[Обсуждение MediaWiki:Robots.txt]] --> | {{^|1em}} | <div class="ts-doc-footer plainlinks"> {{#ifeq: {{str left|{{PAGENAME}}|9}} | Песочница | | {{#ifeq: {{str rightc|{{PAGENAME}}|10}} | /песочница | | Во избежание поломок страниц, исполь...» wikitext text/x-wiki <includeonly></div> </div><templatestyles src="Шаблон:Doc/styles.css" />{{#ifexpr: {{NAMESPACENUMBER}} mod 2 = 1 <!-- Например, [[Обсуждение MediaWiki:Robots.txt]] --> | {{^|1em}} | <div class="ts-doc-footer plainlinks"> {{#ifeq: {{str left|{{PAGENAME}}|9}} | Песочница | | {{#ifeq: {{str rightc|{{PAGENAME}}|10}} | /песочница | | Во избежание поломок страниц, использующих этот {{#ifeq: {{NAMESPACE}} | Модуль | модуль | шаблон }}, экспериментируйте в [[Анонпедия:Правка и тестирование шаблонов в песочнице|песочнице]] <small style="font-style:normal;">({{#ifexist: {{FULLPAGENAME}}/песочница | [{{fullurl:{{FULLPAGENAME}}/песочница|action=edit}} редактировать] {{!}} [{{fullurl:Special:ComparePages|page1={{FULLPAGENAMEE}}&page2={{FULLPAGENAMEE}}/песочница}} разница] {{#ifexist: {{FULLPAGENAME}}/тесты | {{!}} [[{{FULLPAGENAME}}/тесты|тесты]] }} | {{#ifeq: {{NAMESPACE}} | Модуль | [{{fullurl:{{FULLPAGENAME}}/песочница|action=edit}} создать] | [{{fullurl:{{FULLPAGENAME}}/песочница|action=edit&preload=Шаблон:Doc/предзагрузка-песочница}} создать] {{!}} [{{fullurl:{{FULLPAGENAME}}/песочница|action=edit&preload=Шаблон:Doc/зеркало}} зеркало] }} }})</small> или {{#ifeq: {{NAMESPACE}} | Модуль | [[Модуль:Песочница|песочнице для модулей]] | своём [[ВП:ЛП|личном пространстве]] }}.<br> }} }}{{#ifexist: {{FULLPAGENAME}}/doc | Пожалуйста, добавляйте категории на подстраницу [[/doc]].&#32;}}[[Special:PrefixIndex/{{FULLPAGENAME}}/|Подстраницы этого {{#ifeq: {{NAMESPACE}} | Модуль | модуля | шаблона }}]]. </div> }}</includeonly><noinclude>{{doc}}</noinclude> d36d959617c1c876b9769c62baf9d6c9a014476a Шаблон:Ombox 10 20 38 2024-08-08T15:56:53Z DuOfOrl 5 Новая страница: «{{#invoke:Message box|ombox}}<noinclude> {{doc}}<!-- Add categories and interwikis to the /doc subpage, not here! --></noinclude>» wikitext text/x-wiki {{#invoke:Message box|ombox}}<noinclude> {{doc}}<!-- Add categories and interwikis to the /doc subpage, not here! --></noinclude> ab34435c5ebc29de589c9b059e88da5d0e6f16e4 Модуль:Message box 828 21 39 2024-08-08T15:58:46Z DuOfOrl 5 Новая страница: «-- This is a meta-module for producing message box templates, including -- {{mbox}}, {{ambox}}, {{imbox}}, {{tmbox}}, {{ombox}}, {{cmbox}} and {{fmbox}}. -- Load necessary modules. require('strict') local getArgs local categoryHandler = require('Module:Category handler')._main local yesno = require('Module:Yesno') local boxDate = require('Module:Calendar').bxDate; -- Get a language object for formatDate and ucfirst. local lang = mw.language.getContentLangu...» Scribunto text/plain -- This is a meta-module for producing message box templates, including -- {{mbox}}, {{ambox}}, {{imbox}}, {{tmbox}}, {{ombox}}, {{cmbox}} and {{fmbox}}. -- Load necessary modules. require('strict') local getArgs local categoryHandler = require('Module:Category handler')._main local yesno = require('Module:Yesno') local boxDate = require('Module:Calendar').bxDate; -- Get a language object for formatDate and ucfirst. local lang = mw.language.getContentLanguage() -- Define constants local CONFIG_MODULE = 'Module:Message box/configuration' -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function getTitleObject(...) -- Get the title object, passing the function through pcall -- in case we are over the expensive function count limit. local success, title = pcall(mw.title.new, ...) if success then return title end end local function union(t1, t2) -- Returns the union of two arrays. local vals = {} for i, v in ipairs(t1) do vals[v] = true end for i, v in ipairs(t2) do vals[v] = true end local ret = {} for k in pairs(vals) do table.insert(ret, k) end table.sort(ret) return ret end local function getArgNums(args, prefix) local nums = {} for k, v in pairs(args) do local num = mw.ustring.match(tostring(k), '^' .. prefix .. '([1-9]%d*)$') if num then table.insert(nums, tonumber(num)) end end table.sort(nums) return nums end -- локальная обёртка, игнорирует таблицу с номерами дня, месяца и года local function formatDate(txtDateIn, strFormat, params) local txtDateOut, date, status = boxDate(txtDateIn, strFormat, params) if status.brk then return error(status.errorText) else return txtDateOut end end -------------------------------------------------------------------------------- -- Box class definition -------------------------------------------------------------------------------- local MessageBox = {} MessageBox.__index = MessageBox function MessageBox.new(boxType, args, cfg) args = args or {} local obj = {} -- Set the title object and the namespace. obj.title = getTitleObject(args.page) or mw.title.getCurrentTitle() -- Set the config for our box type. obj.cfg = cfg[boxType] if not obj.cfg then local ns = obj.title.namespace -- boxType is "mbox" or invalid input if ns == 0 then obj.cfg = cfg.ambox -- main namespace elseif ns == 6 then obj.cfg = cfg.imbox -- file namespace elseif ns == 14 then obj.cfg = cfg.cmbox -- category namespace else local nsTable = mw.site.namespaces[ns] if nsTable and nsTable.isTalk then obj.cfg = cfg.tmbox -- any talk namespace else obj.cfg = cfg.ombox -- other namespaces or invalid input end end end -- Set the arguments, and remove all blank arguments except for the ones -- listed in cfg.allowBlankParams. do local newArgs = {} for k, v in pairs(args) do if v ~= '' then newArgs[k] = v end end for i, param in ipairs(obj.cfg.allowBlankParams or {}) do newArgs[param] = args[param] end obj.args = newArgs end -- Define internal data structure. obj.categories = {} obj.classes = {} return setmetatable(obj, MessageBox) end function MessageBox:addCat(ns, cat, sort) if not cat then return nil end if sort then cat = string.format('[[Категория:%s|%s]]', cat, sort) else cat = string.format('[[Категория:%s]]', cat) end self.categories[ns] = self.categories[ns] or {} table.insert(self.categories[ns], cat) end function MessageBox:addClass(class) if not class then return nil end table.insert(self.classes, class) end function MessageBox:setParameters() local args = self.args local cfg = self.cfg -- Get type data. self.type = args.type local typeData = cfg.types[self.type] self.invalidTypeError = cfg.showInvalidTypeError and self.type and not typeData typeData = typeData or cfg.types[cfg.default] self.typeClass = typeData.class self.typeImage = typeData.image -- Find if the box has been wrongly substituted. self.isSubstituted = cfg.substCheck and args.subst == 'SUBST' -- Find whether we are using a small message box. self.isSmall = cfg.allowSmall and ( cfg.smallParam and args.small == cfg.smallParam or not cfg.smallParam and yesno(args.small) ) -- Add attributes, classes and styles. self.id = args.id self.name = args.name if self.name then self:addClass('mbox-' .. string.gsub(self.name,' ','_')) end if yesno(args.plainlinks) ~= false then self:addClass('plainlinks') end for _, class in ipairs(cfg.classes or {}) do self:addClass(class) end if self.isSmall then self:addClass(cfg.smallClass or 'mbox-small') end self:addClass(self.typeClass) self:addClass(args.class) self.style = args.style self.attrs = args.attrs self.dataLabel1 = args['data-label-1'] self.dataLabel2 = args['data-label-2'] self.dataLabel3 = args['data-label-3'] self.dataValue1 = args['data-value-1'] self.dataValue2 = args['data-value-2'] self.dataValue3 = args['data-value-3'] -- Set text style. self.textstyle = args.textstyle -- Find if we are on the template page or not. This functionality is only -- used if useCollapsibleTextFields is set, or if both cfg.templateCategory -- and cfg.templateCategoryRequireName are set. self.useCollapsibleTextFields = cfg.useCollapsibleTextFields if self.useCollapsibleTextFields or cfg.templateCategory and cfg.templateCategoryRequireName then self.name = args.name if self.name then local templateName = mw.ustring.match( self.name, '^[tT][eE][mM][pP][lL][aA][tT][eE][%s_]*:[%s_]*(.*)$' ) or self.name templateName = ('Template:' .. templateName) or ('Шаблон:' .. templateName) self.templateTitle = getTitleObject(templateName) end self.isTemplatePage = self.templateTitle and mw.title.equals(self.title, self.templateTitle) end -- Process data for collapsible text fields. At the moment these are only -- used in {{ambox}}. if self.useCollapsibleTextFields then -- Get the self.issue value. if self.isSmall and args.smalltext then self.issue = args.smalltext else if args.sect and args.sect ~= '' or nil then local issue_sect = args.issue_sect issue_sect = type(issue_sect) == 'string' and issue_sect ~= '' and issue_sect or nil local text_sect = args.text_sect text_sect = type(text_sect) == 'string' and text_sect ~= '' and text_sect or nil local issues = {} table.insert(issues, issue_sect) table.insert(issues, text_sect) self.issue = table.concat(issues, ' ') else local issue = args.issue issue = type(issue) == 'string' and issue ~= '' and issue or nil local text = args.text text = type(text) == 'string' and text or nil local issues = {} table.insert(issues, issue) table.insert(issues, text) self.issue = table.concat(issues, ' ') end end -- Get the self.talk value. local talk = args.talk -- Show talk links on the template page or template subpages if the talk -- parameter is blank. if talk == '' and self.templateTitle and ( mw.title.equals(self.templateTitle, self.title) or self.title:isSubpageOf(self.templateTitle) ) then talk = '#' elseif talk == '' then talk = nil end if talk then -- If the talk value is a talk page, make a link to that page. Else -- assume that it's a section heading, and make a link to the talk -- page of the current page with that section heading. local talkTitle = getTitleObject(talk) local talkArgIsTalkPage = true if not talkTitle or not talkTitle.isTalkPage then talkArgIsTalkPage = false talkTitle = getTitleObject( self.title.text, mw.site.namespaces[self.title.namespace].talk.id ) end if talkTitle and talkTitle.exists then local talkText = 'Соответствующую дискуссию можно найти на' if talkArgIsTalkPage then talkText = string.format( '%s [[%s|%s]].', talkText, talk, talkTitle.prefixedText ) else talkText = string.format( '%s [[%s#%s|странице обсуждения]].', talkText, talkTitle.prefixedText, talk ) end self.talk = talkText end end -- Get other values. self.fix = args.fix ~= '' and args.fix or nil local date if args.date and args.date ~= '' then local status, result = pcall(formatDate, args.date) if status then date = string.format("(<span class='date'>%s</span>)", result) else date = string.format("<span class='error'>(Строка «%s» не является верной датой, пожалуйста, укажите дату в формате <code>ГГГГ-ММ-ДД</code>)</span>", args.date) end elseif args.date == '' and self.isTemplatePage then date = string.format("(<span class='date'>%s</span>)", formatDate( lang:formatDate('Y-m-d') ) ) -- тут возникновения ошибки, связанной с пользовательским вводом, не будет end if date then self.date = string.format(" <span class='mbox-date'>''%s''</span>", date) end self.info = args.info if yesno(args.removalnotice) then self.removalNotice = cfg.removalNotice end if args.shortFix then self.shortFix = args.shortFix end end -- Set the non-collapsible text field. At the moment this is used by all box -- types other than ambox, and also by ambox when small=yes. if self.isSmall then self.text = args.smalltext or args.text else self.text = args.text self.textsmall = args['text-small'] end -- Set the below row. self.below = cfg.below and args.below -- General image settings. self.imageCellDiv = not self.isSmall and cfg.imageCellDiv self.imageEmptyCell = cfg.imageEmptyCell if cfg.imageEmptyCellStyle then self.imageEmptyCellStyle = 'border:none;padding:0px;width:1px' end -- Left image settings. local imageLeft = self.isSmall and args.smallimage or args.image if cfg.imageCheckBlank and imageLeft ~= 'blank' and imageLeft ~= 'none' and imageLeft ~= '' or not cfg.imageCheckBlank and imageLeft ~= 'none' then self.imageLeft = imageLeft if not imageLeft then local imageSize = self.isSmall and (cfg.imageSmallSize or '30x30px') or cfg.imageSize or '40x40px' self.imageLeft = string.format('[[File:%s|%s|alt=]]', self.typeImage or 'Information icon4.svg', imageSize) end end -- Right image settings. local imageRight = self.isSmall and args.smallimageright or args.imageright if not (cfg.imageRightNone and imageRight == 'none') then self.imageRight = imageRight end -- set templatestyles self.base_templatestyles = cfg.templatestyles end function MessageBox:setMainspaceCategories() local args = self.args local cfg = self.cfg local date = nil if not cfg.allowMainspaceCategories then return nil end local nums = {} for _, prefix in ipairs{'cat', 'category', 'all'} do args[prefix .. '1'] = args[prefix] nums = union(nums, getArgNums(args, prefix)) end -- The following is roughly equivalent to the old {{Ambox/category}}. local status, result = pcall(formatDate, args.date, 'xg Y') if status then date = result end date = type(date) == 'string' and date local preposition = 'с' local suffix = 'года' for _, num in ipairs(nums) do local mainCat = args['cat' .. tostring(num)] or args['category' .. tostring(num)] local allCat = args['all' .. tostring(num)] mainCat = type(mainCat) == 'string' and mainCat allCat = type(allCat) == 'string' and allCat if mainCat and date and date ~= '' then local catTitle = string.format('%s %s %s %s', mainCat, preposition, date, suffix) self:addCat(0, catTitle) catTitle = getTitleObject('Категория:' .. catTitle) local status, result = pcall(formatDate, args.date) if not status then self:addCat(0, 'Википедия:Статьи с недопустимым параметром даты в шаблоне-сообщении') end elseif mainCat and (not date or date == '') then self:addCat(0, mainCat) end if allCat then self:addCat(0, allCat) end end end function MessageBox:setTemplateCategories() local args = self.args local cfg = self.cfg -- Add template categories. if cfg.templateCategory then if cfg.templateCategoryRequireName then if self.isTemplatePage then self:addCat(10, cfg.templateCategory) end elseif not self.title.isSubpage then self:addCat(10, cfg.templateCategory) end end -- Add template error categories. if cfg.templateErrorCategory then local templateErrorCategory = cfg.templateErrorCategory local templateCat, templateSort if not self.name and not self.title.isSubpage then templateCat = templateErrorCategory elseif self.isTemplatePage then local paramsToCheck = cfg.templateErrorParamsToCheck or {} local count = 0 for i, param in ipairs(paramsToCheck) do if not args[param] then count = count + 1 end end if count > 0 then templateCat = templateErrorCategory templateSort = tostring(count) end if self.categoryNums and #self.categoryNums > 0 then templateCat = templateErrorCategory templateSort = 'C' end end self:addCat(10, templateCat, templateSort) end end function MessageBox:setAllNamespaceCategories() -- Set categories for all namespaces. if self.invalidTypeError then local allSort = (self.title.namespace == 0 and 'Main:' or '') .. self.title.prefixedText self:addCat('all', 'Википедия:Необходимо исправить параметр в шаблоне-сообщении', allSort) end if self.isSubstituted then self:addCat('all', 'Википедия:Страницы с ошибочно подставленными шаблонами') end if self.isSmall then self:addCat(0, 'Википедия:Страницы с малыми шаблонами-сообщениями') end end function MessageBox:setCategories() if self.title.namespace == 0 then self:setMainspaceCategories() elseif self.title.namespace == 10 then self:setTemplateCategories() end self:setAllNamespaceCategories() end function MessageBox:renderCategories() -- Convert category tables to strings and pass them through -- [[Module:Category handler]]. return categoryHandler{ main = table.concat(self.categories[0] or {}), template = table.concat(self.categories[10] or {}), all = table.concat(self.categories.all or {}), nocat = self.args.nocat, page = self.args.page } end function MessageBox:export() local root = mw.html.create() -- Add the subst check error. if self.isSubstituted and self.name then root:tag('b') :addClass('error') :wikitext(string.format( 'Шаблон <code>%s[[Шаблон:%s|%s]]%s</code> был неккоректно подставлен.', mw.text.nowiki('{{'), self.name, self.name, mw.text.nowiki('}}') )) end -- Conditional TemplateStyles loading if self.base_templatestyles then local frame = mw.getCurrentFrame() root:wikitext(frame:extensionTag{ name = 'templatestyles', args = { src = self.base_templatestyles }, }) end -- Create the box table. local boxTable = root:tag('table') boxTable:attr('id', self.id or nil) for i, class in ipairs(self.classes or {}) do boxTable:addClass(class or nil) end boxTable :cssText(self.style or nil) :attr('role', 'presentation') if self.dataLabel1 then boxTable:attr('data-' .. self.dataLabel1, self.dataValue1) end if self.dataLabel2 then boxTable:attr('data-' .. self.dataLabel2, self.dataValue2) end if self.dataLabel3 then boxTable:attr('data-' .. self.dataLabel3, self.dataValue3) end if self.attrs then boxTable:attr(self.attrs) end -- Add the left-hand image. local row = boxTable:tag('tr') if self.imageLeft then local imageLeftCell = row:tag('td'):addClass('mbox-image') if self.imageCellDiv then -- If we are using a div, redefine imageLeftCell so that the image -- is inside it. Divs use style="width: 52px;", which limits the -- image width to 52px. If any images in a div are wider than that, -- they may overlap with the text or cause other display problems. imageLeftCell = imageLeftCell:tag('div'):css('width', '52px') end imageLeftCell:wikitext(self.imageLeft or nil) elseif self.imageEmptyCell then -- Some message boxes define an empty cell if no image is specified, and -- some don't. The old template code in templates where empty cells are -- specified gives the following hint: "No image. Cell with some width -- or padding necessary for text cell to have 100% width." row:tag('td') :addClass('mbox-empty-cell') :cssText(self.imageEmptyCellStyle or nil) end -- Add the text. local textCell = row:tag('td'):addClass('mbox-text') if self.useCollapsibleTextFields then -- The message box uses advanced text parameters that allow things to be -- collapsible. At the moment, only ambox uses this. textCell:cssText(self.textstyle or nil) local textCellDiv = textCell:tag('div') textCellDiv :addClass('mbox-text-div') :wikitext(self.issue or nil) local textsmallCellDiv = textCell:tag('div') textsmallCellDiv :addClass('mbox-textsmall-div hide-when-compact') :cssText(self.textsmallstyle) :wikitext(self.textsmall or nil) if (self.talk or self.fix) and not self.isSmall then textsmallCellDiv:tag('span') :addClass('hide-when-compact') :wikitext(self.fix and (' ' .. self.fix) or nil) :wikitext(self.talk and (' ' .. self.talk) or nil) end if self.textsmall or self.fix or self.talk then textsmallCellDiv:wikitext(self.date and (' ' .. self.date) or nil) else textCellDiv:wikitext(self.date and (' ' .. self.date) or nil) end if self.info and not self.isSmall then textsmallCellDiv :tag('span') :addClass('hide-when-compact') :wikitext(self.info and (' ' .. self.info) or nil) end if self.removalNotice then textsmallCellDiv:tag('small') :addClass('hide-when-compact') :tag('i') :wikitext(string.format(" (%s)", self.removalNotice)) end if self.shortFix then textCell:tag('div') :addClass('mbox-multiply') :tag('span') :wikitext(string.format("%s", self.shortFix)) :tag('span') :wikitext(self.date and (' ' .. self.date) or nil) end else -- Default text formatting - anything goes. textCell :cssText(self.textstyle or nil) :wikitext(self.text or nil) end -- Add the right-hand image. if self.imageRight then local imageRightCell = row:tag('td'):addClass('mbox-imageright') if self.imageCellDiv then -- If we are using a div, redefine imageRightCell so that the image -- is inside it. imageRightCell = imageRightCell:tag('div'):css('width', '52px') end imageRightCell :wikitext(self.imageRight or nil) end -- Add the below row. if self.below then boxTable:tag('tr') :tag('td') :attr('colspan', self.imageRight and '3' or '2') :addClass('mbox-text') :cssText(self.textstyle or nil) :wikitext(self.below or nil) end -- Add error message for invalid type parameters. if self.invalidTypeError then root:tag('div') :css('text-align', 'center') :wikitext(string.format( 'Этот шаблон-сообщение использует неверный параметр "type=%s", необходимо исправить.', self.type or '' )) end -- Add categories. root:wikitext(self:renderCategories() or nil) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p, mt = {}, {} function p._exportClasses() -- For testing. return { MessageBox = MessageBox } end function p.main(boxType, args, cfgTables) local box = MessageBox.new(boxType, args, cfgTables or mw.loadData(CONFIG_MODULE)) box:setParameters() box:setCategories() return box:export() end function mt.__index(t, k) return function (frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end return t.main(k, getArgs(frame, {trim = false, removeBlanks = false})) end end return setmetatable(p, mt) f2539b657a9cdadde7c0dd5ad270d3095b2bdd54 137 39 2024-08-09T17:01:57Z DuOfOrl 5 1 версия импортирована Scribunto text/plain -- This is a meta-module for producing message box templates, including -- {{mbox}}, {{ambox}}, {{imbox}}, {{tmbox}}, {{ombox}}, {{cmbox}} and {{fmbox}}. -- Load necessary modules. require('strict') local getArgs local categoryHandler = require('Module:Category handler')._main local yesno = require('Module:Yesno') local boxDate = require('Module:Calendar').bxDate; -- Get a language object for formatDate and ucfirst. local lang = mw.language.getContentLanguage() -- Define constants local CONFIG_MODULE = 'Module:Message box/configuration' -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function getTitleObject(...) -- Get the title object, passing the function through pcall -- in case we are over the expensive function count limit. local success, title = pcall(mw.title.new, ...) if success then return title end end local function union(t1, t2) -- Returns the union of two arrays. local vals = {} for i, v in ipairs(t1) do vals[v] = true end for i, v in ipairs(t2) do vals[v] = true end local ret = {} for k in pairs(vals) do table.insert(ret, k) end table.sort(ret) return ret end local function getArgNums(args, prefix) local nums = {} for k, v in pairs(args) do local num = mw.ustring.match(tostring(k), '^' .. prefix .. '([1-9]%d*)$') if num then table.insert(nums, tonumber(num)) end end table.sort(nums) return nums end -- локальная обёртка, игнорирует таблицу с номерами дня, месяца и года local function formatDate(txtDateIn, strFormat, params) local txtDateOut, date, status = boxDate(txtDateIn, strFormat, params) if status.brk then return error(status.errorText) else return txtDateOut end end -------------------------------------------------------------------------------- -- Box class definition -------------------------------------------------------------------------------- local MessageBox = {} MessageBox.__index = MessageBox function MessageBox.new(boxType, args, cfg) args = args or {} local obj = {} -- Set the title object and the namespace. obj.title = getTitleObject(args.page) or mw.title.getCurrentTitle() -- Set the config for our box type. obj.cfg = cfg[boxType] if not obj.cfg then local ns = obj.title.namespace -- boxType is "mbox" or invalid input if ns == 0 then obj.cfg = cfg.ambox -- main namespace elseif ns == 6 then obj.cfg = cfg.imbox -- file namespace elseif ns == 14 then obj.cfg = cfg.cmbox -- category namespace else local nsTable = mw.site.namespaces[ns] if nsTable and nsTable.isTalk then obj.cfg = cfg.tmbox -- any talk namespace else obj.cfg = cfg.ombox -- other namespaces or invalid input end end end -- Set the arguments, and remove all blank arguments except for the ones -- listed in cfg.allowBlankParams. do local newArgs = {} for k, v in pairs(args) do if v ~= '' then newArgs[k] = v end end for i, param in ipairs(obj.cfg.allowBlankParams or {}) do newArgs[param] = args[param] end obj.args = newArgs end -- Define internal data structure. obj.categories = {} obj.classes = {} return setmetatable(obj, MessageBox) end function MessageBox:addCat(ns, cat, sort) if not cat then return nil end if sort then cat = string.format('[[Категория:%s|%s]]', cat, sort) else cat = string.format('[[Категория:%s]]', cat) end self.categories[ns] = self.categories[ns] or {} table.insert(self.categories[ns], cat) end function MessageBox:addClass(class) if not class then return nil end table.insert(self.classes, class) end function MessageBox:setParameters() local args = self.args local cfg = self.cfg -- Get type data. self.type = args.type local typeData = cfg.types[self.type] self.invalidTypeError = cfg.showInvalidTypeError and self.type and not typeData typeData = typeData or cfg.types[cfg.default] self.typeClass = typeData.class self.typeImage = typeData.image -- Find if the box has been wrongly substituted. self.isSubstituted = cfg.substCheck and args.subst == 'SUBST' -- Find whether we are using a small message box. self.isSmall = cfg.allowSmall and ( cfg.smallParam and args.small == cfg.smallParam or not cfg.smallParam and yesno(args.small) ) -- Add attributes, classes and styles. self.id = args.id self.name = args.name if self.name then self:addClass('mbox-' .. string.gsub(self.name,' ','_')) end if yesno(args.plainlinks) ~= false then self:addClass('plainlinks') end for _, class in ipairs(cfg.classes or {}) do self:addClass(class) end if self.isSmall then self:addClass(cfg.smallClass or 'mbox-small') end self:addClass(self.typeClass) self:addClass(args.class) self.style = args.style self.attrs = args.attrs self.dataLabel1 = args['data-label-1'] self.dataLabel2 = args['data-label-2'] self.dataLabel3 = args['data-label-3'] self.dataValue1 = args['data-value-1'] self.dataValue2 = args['data-value-2'] self.dataValue3 = args['data-value-3'] -- Set text style. self.textstyle = args.textstyle -- Find if we are on the template page or not. This functionality is only -- used if useCollapsibleTextFields is set, or if both cfg.templateCategory -- and cfg.templateCategoryRequireName are set. self.useCollapsibleTextFields = cfg.useCollapsibleTextFields if self.useCollapsibleTextFields or cfg.templateCategory and cfg.templateCategoryRequireName then self.name = args.name if self.name then local templateName = mw.ustring.match( self.name, '^[tT][eE][mM][pP][lL][aA][tT][eE][%s_]*:[%s_]*(.*)$' ) or self.name templateName = ('Template:' .. templateName) or ('Шаблон:' .. templateName) self.templateTitle = getTitleObject(templateName) end self.isTemplatePage = self.templateTitle and mw.title.equals(self.title, self.templateTitle) end -- Process data for collapsible text fields. At the moment these are only -- used in {{ambox}}. if self.useCollapsibleTextFields then -- Get the self.issue value. if self.isSmall and args.smalltext then self.issue = args.smalltext else if args.sect and args.sect ~= '' or nil then local issue_sect = args.issue_sect issue_sect = type(issue_sect) == 'string' and issue_sect ~= '' and issue_sect or nil local text_sect = args.text_sect text_sect = type(text_sect) == 'string' and text_sect ~= '' and text_sect or nil local issues = {} table.insert(issues, issue_sect) table.insert(issues, text_sect) self.issue = table.concat(issues, ' ') else local issue = args.issue issue = type(issue) == 'string' and issue ~= '' and issue or nil local text = args.text text = type(text) == 'string' and text or nil local issues = {} table.insert(issues, issue) table.insert(issues, text) self.issue = table.concat(issues, ' ') end end -- Get the self.talk value. local talk = args.talk -- Show talk links on the template page or template subpages if the talk -- parameter is blank. if talk == '' and self.templateTitle and ( mw.title.equals(self.templateTitle, self.title) or self.title:isSubpageOf(self.templateTitle) ) then talk = '#' elseif talk == '' then talk = nil end if talk then -- If the talk value is a talk page, make a link to that page. Else -- assume that it's a section heading, and make a link to the talk -- page of the current page with that section heading. local talkTitle = getTitleObject(talk) local talkArgIsTalkPage = true if not talkTitle or not talkTitle.isTalkPage then talkArgIsTalkPage = false talkTitle = getTitleObject( self.title.text, mw.site.namespaces[self.title.namespace].talk.id ) end if talkTitle and talkTitle.exists then local talkText = 'Соответствующую дискуссию можно найти на' if talkArgIsTalkPage then talkText = string.format( '%s [[%s|%s]].', talkText, talk, talkTitle.prefixedText ) else talkText = string.format( '%s [[%s#%s|странице обсуждения]].', talkText, talkTitle.prefixedText, talk ) end self.talk = talkText end end -- Get other values. self.fix = args.fix ~= '' and args.fix or nil local date if args.date and args.date ~= '' then local status, result = pcall(formatDate, args.date) if status then date = string.format("(<span class='date'>%s</span>)", result) else date = string.format("<span class='error'>(Строка «%s» не является верной датой, пожалуйста, укажите дату в формате <code>ГГГГ-ММ-ДД</code>)</span>", args.date) end elseif args.date == '' and self.isTemplatePage then date = string.format("(<span class='date'>%s</span>)", formatDate( lang:formatDate('Y-m-d') ) ) -- тут возникновения ошибки, связанной с пользовательским вводом, не будет end if date then self.date = string.format(" <span class='mbox-date'>''%s''</span>", date) end self.info = args.info if yesno(args.removalnotice) then self.removalNotice = cfg.removalNotice end if args.shortFix then self.shortFix = args.shortFix end end -- Set the non-collapsible text field. At the moment this is used by all box -- types other than ambox, and also by ambox when small=yes. if self.isSmall then self.text = args.smalltext or args.text else self.text = args.text self.textsmall = args['text-small'] end -- Set the below row. self.below = cfg.below and args.below -- General image settings. self.imageCellDiv = not self.isSmall and cfg.imageCellDiv self.imageEmptyCell = cfg.imageEmptyCell if cfg.imageEmptyCellStyle then self.imageEmptyCellStyle = 'border:none;padding:0px;width:1px' end -- Left image settings. local imageLeft = self.isSmall and args.smallimage or args.image if cfg.imageCheckBlank and imageLeft ~= 'blank' and imageLeft ~= 'none' and imageLeft ~= '' or not cfg.imageCheckBlank and imageLeft ~= 'none' then self.imageLeft = imageLeft if not imageLeft then local imageSize = self.isSmall and (cfg.imageSmallSize or '30x30px') or cfg.imageSize or '40x40px' self.imageLeft = string.format('[[File:%s|%s|alt=]]', self.typeImage or 'Information icon4.svg', imageSize) end end -- Right image settings. local imageRight = self.isSmall and args.smallimageright or args.imageright if not (cfg.imageRightNone and imageRight == 'none') then self.imageRight = imageRight end -- set templatestyles self.base_templatestyles = cfg.templatestyles end function MessageBox:setMainspaceCategories() local args = self.args local cfg = self.cfg local date = nil if not cfg.allowMainspaceCategories then return nil end local nums = {} for _, prefix in ipairs{'cat', 'category', 'all'} do args[prefix .. '1'] = args[prefix] nums = union(nums, getArgNums(args, prefix)) end -- The following is roughly equivalent to the old {{Ambox/category}}. local status, result = pcall(formatDate, args.date, 'xg Y') if status then date = result end date = type(date) == 'string' and date local preposition = 'с' local suffix = 'года' for _, num in ipairs(nums) do local mainCat = args['cat' .. tostring(num)] or args['category' .. tostring(num)] local allCat = args['all' .. tostring(num)] mainCat = type(mainCat) == 'string' and mainCat allCat = type(allCat) == 'string' and allCat if mainCat and date and date ~= '' then local catTitle = string.format('%s %s %s %s', mainCat, preposition, date, suffix) self:addCat(0, catTitle) catTitle = getTitleObject('Категория:' .. catTitle) local status, result = pcall(formatDate, args.date) if not status then self:addCat(0, 'Википедия:Статьи с недопустимым параметром даты в шаблоне-сообщении') end elseif mainCat and (not date or date == '') then self:addCat(0, mainCat) end if allCat then self:addCat(0, allCat) end end end function MessageBox:setTemplateCategories() local args = self.args local cfg = self.cfg -- Add template categories. if cfg.templateCategory then if cfg.templateCategoryRequireName then if self.isTemplatePage then self:addCat(10, cfg.templateCategory) end elseif not self.title.isSubpage then self:addCat(10, cfg.templateCategory) end end -- Add template error categories. if cfg.templateErrorCategory then local templateErrorCategory = cfg.templateErrorCategory local templateCat, templateSort if not self.name and not self.title.isSubpage then templateCat = templateErrorCategory elseif self.isTemplatePage then local paramsToCheck = cfg.templateErrorParamsToCheck or {} local count = 0 for i, param in ipairs(paramsToCheck) do if not args[param] then count = count + 1 end end if count > 0 then templateCat = templateErrorCategory templateSort = tostring(count) end if self.categoryNums and #self.categoryNums > 0 then templateCat = templateErrorCategory templateSort = 'C' end end self:addCat(10, templateCat, templateSort) end end function MessageBox:setAllNamespaceCategories() -- Set categories for all namespaces. if self.invalidTypeError then local allSort = (self.title.namespace == 0 and 'Main:' or '') .. self.title.prefixedText self:addCat('all', 'Википедия:Необходимо исправить параметр в шаблоне-сообщении', allSort) end if self.isSubstituted then self:addCat('all', 'Википедия:Страницы с ошибочно подставленными шаблонами') end if self.isSmall then self:addCat(0, 'Википедия:Страницы с малыми шаблонами-сообщениями') end end function MessageBox:setCategories() if self.title.namespace == 0 then self:setMainspaceCategories() elseif self.title.namespace == 10 then self:setTemplateCategories() end self:setAllNamespaceCategories() end function MessageBox:renderCategories() -- Convert category tables to strings and pass them through -- [[Module:Category handler]]. return categoryHandler{ main = table.concat(self.categories[0] or {}), template = table.concat(self.categories[10] or {}), all = table.concat(self.categories.all or {}), nocat = self.args.nocat, page = self.args.page } end function MessageBox:export() local root = mw.html.create() -- Add the subst check error. if self.isSubstituted and self.name then root:tag('b') :addClass('error') :wikitext(string.format( 'Шаблон <code>%s[[Шаблон:%s|%s]]%s</code> был неккоректно подставлен.', mw.text.nowiki('{{'), self.name, self.name, mw.text.nowiki('}}') )) end -- Conditional TemplateStyles loading if self.base_templatestyles then local frame = mw.getCurrentFrame() root:wikitext(frame:extensionTag{ name = 'templatestyles', args = { src = self.base_templatestyles }, }) end -- Create the box table. local boxTable = root:tag('table') boxTable:attr('id', self.id or nil) for i, class in ipairs(self.classes or {}) do boxTable:addClass(class or nil) end boxTable :cssText(self.style or nil) :attr('role', 'presentation') if self.dataLabel1 then boxTable:attr('data-' .. self.dataLabel1, self.dataValue1) end if self.dataLabel2 then boxTable:attr('data-' .. self.dataLabel2, self.dataValue2) end if self.dataLabel3 then boxTable:attr('data-' .. self.dataLabel3, self.dataValue3) end if self.attrs then boxTable:attr(self.attrs) end -- Add the left-hand image. local row = boxTable:tag('tr') if self.imageLeft then local imageLeftCell = row:tag('td'):addClass('mbox-image') if self.imageCellDiv then -- If we are using a div, redefine imageLeftCell so that the image -- is inside it. Divs use style="width: 52px;", which limits the -- image width to 52px. If any images in a div are wider than that, -- they may overlap with the text or cause other display problems. imageLeftCell = imageLeftCell:tag('div'):css('width', '52px') end imageLeftCell:wikitext(self.imageLeft or nil) elseif self.imageEmptyCell then -- Some message boxes define an empty cell if no image is specified, and -- some don't. The old template code in templates where empty cells are -- specified gives the following hint: "No image. Cell with some width -- or padding necessary for text cell to have 100% width." row:tag('td') :addClass('mbox-empty-cell') :cssText(self.imageEmptyCellStyle or nil) end -- Add the text. local textCell = row:tag('td'):addClass('mbox-text') if self.useCollapsibleTextFields then -- The message box uses advanced text parameters that allow things to be -- collapsible. At the moment, only ambox uses this. textCell:cssText(self.textstyle or nil) local textCellDiv = textCell:tag('div') textCellDiv :addClass('mbox-text-div') :wikitext(self.issue or nil) local textsmallCellDiv = textCell:tag('div') textsmallCellDiv :addClass('mbox-textsmall-div hide-when-compact') :cssText(self.textsmallstyle) :wikitext(self.textsmall or nil) if (self.talk or self.fix) and not self.isSmall then textsmallCellDiv:tag('span') :addClass('hide-when-compact') :wikitext(self.fix and (' ' .. self.fix) or nil) :wikitext(self.talk and (' ' .. self.talk) or nil) end if self.textsmall or self.fix or self.talk then textsmallCellDiv:wikitext(self.date and (' ' .. self.date) or nil) else textCellDiv:wikitext(self.date and (' ' .. self.date) or nil) end if self.info and not self.isSmall then textsmallCellDiv :tag('span') :addClass('hide-when-compact') :wikitext(self.info and (' ' .. self.info) or nil) end if self.removalNotice then textsmallCellDiv:tag('small') :addClass('hide-when-compact') :tag('i') :wikitext(string.format(" (%s)", self.removalNotice)) end if self.shortFix then textCell:tag('div') :addClass('mbox-multiply') :tag('span') :wikitext(string.format("%s", self.shortFix)) :tag('span') :wikitext(self.date and (' ' .. self.date) or nil) end else -- Default text formatting - anything goes. textCell :cssText(self.textstyle or nil) :wikitext(self.text or nil) end -- Add the right-hand image. if self.imageRight then local imageRightCell = row:tag('td'):addClass('mbox-imageright') if self.imageCellDiv then -- If we are using a div, redefine imageRightCell so that the image -- is inside it. imageRightCell = imageRightCell:tag('div'):css('width', '52px') end imageRightCell :wikitext(self.imageRight or nil) end -- Add the below row. if self.below then boxTable:tag('tr') :tag('td') :attr('colspan', self.imageRight and '3' or '2') :addClass('mbox-text') :cssText(self.textstyle or nil) :wikitext(self.below or nil) end -- Add error message for invalid type parameters. if self.invalidTypeError then root:tag('div') :css('text-align', 'center') :wikitext(string.format( 'Этот шаблон-сообщение использует неверный параметр "type=%s", необходимо исправить.', self.type or '' )) end -- Add categories. root:wikitext(self:renderCategories() or nil) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p, mt = {}, {} function p._exportClasses() -- For testing. return { MessageBox = MessageBox } end function p.main(boxType, args, cfgTables) local box = MessageBox.new(boxType, args, cfgTables or mw.loadData(CONFIG_MODULE)) box:setParameters() box:setCategories() return box:export() end function mt.__index(t, k) return function (frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end return t.main(k, getArgs(frame, {trim = false, removeBlanks = false})) end end return setmetatable(p, mt) f2539b657a9cdadde7c0dd5ad270d3095b2bdd54 Модуль:Category handler 828 31 49 2024-08-08T16:13:24Z DuOfOrl 5 Новая страница: «-------------------------------------------------------------------------------- -- -- -- CATEGORY HANDLER -- -- -- -- This module implements the {{category handler}} template in Lua, -- -- with a few improvements: all namespaces and all n...» Scribunto text/plain -------------------------------------------------------------------------------- -- -- -- CATEGORY HANDLER -- -- -- -- This module implements the {{category handler}} template in Lua, -- -- with a few improvements: all namespaces and all namespace aliases -- -- are supported, and namespace names are detected automatically for -- -- the local wiki. This module requires [[Module:Namespace detect]] -- -- and [[Module:Yesno]] to be available on the local wiki. It can be -- -- configured for different wikis by altering the values in -- -- [[Module:Category handler/config]], and pages can be blacklisted -- -- from categorisation by using [[Module:Category handler/blacklist]]. -- -- -- -------------------------------------------------------------------------------- -- Load required modules local yesno = require('Module:Yesno') -- Lazily load things we don't always need local mShared, mappings local p = {} -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function trimWhitespace(s, removeBlanks) if type(s) ~= 'string' then return s end s = s:match('^%s*(.-)%s*$') if removeBlanks then if s ~= '' then return s else return nil end else return s end end -------------------------------------------------------------------------------- -- CategoryHandler class -------------------------------------------------------------------------------- local CategoryHandler = {} CategoryHandler.__index = CategoryHandler function CategoryHandler.new(data, args) local obj = setmetatable({ _data = data, _args = args }, CategoryHandler) -- Set the title object do local pagename = obj:parameter('demopage') local success, titleObj if pagename then success, titleObj = pcall(mw.title.new, pagename) end if success and titleObj then obj.title = titleObj if titleObj == mw.title.getCurrentTitle() then obj._usesCurrentTitle = true end else obj.title = mw.title.getCurrentTitle() obj._usesCurrentTitle = true end end -- Set suppression parameter values for _, key in ipairs{'nocat', 'categories'} do local value = obj:parameter(key) value = trimWhitespace(value, true) obj['_' .. key] = yesno(value) end do local subpage = obj:parameter('subpage') local category2 = obj:parameter('category2') if type(subpage) == 'string' then subpage = mw.ustring.lower(subpage) end if type(category2) == 'string' then subpage = mw.ustring.lower(category2) end obj._subpage = trimWhitespace(subpage, true) obj._category2 = trimWhitespace(category2) -- don't remove blank values end return obj end function CategoryHandler:parameter(key) local parameterNames = self._data.parameters[key] local pntype = type(parameterNames) if pntype == 'string' or pntype == 'number' then return self._args[parameterNames] elseif pntype == 'table' then for _, name in ipairs(parameterNames) do local value = self._args[name] if value ~= nil then return value end end return nil else error(string.format( 'invalid config key "%s"', tostring(key) ), 2) end end function CategoryHandler:isSuppressedByArguments() return -- See if a category suppression argument has been set. self._nocat == true or self._categories == false or ( self._category2 and self._category2 ~= self._data.category2Yes and self._category2 ~= self._data.category2Negative ) -- Check whether we are on a subpage, and see if categories are -- suppressed based on our subpage status. or self._subpage == self._data.subpageNo and self.title.isSubpage or self._subpage == self._data.subpageOnly and not self.title.isSubpage end function CategoryHandler:shouldSkipBlacklistCheck() -- Check whether the category suppression arguments indicate we -- should skip the blacklist check. return self._nocat == false or self._categories == true or self._category2 == self._data.category2Yes end function CategoryHandler:matchesBlacklist() if self._usesCurrentTitle then return self._data.currentTitleMatchesBlacklist else mShared = mShared or require('Module:Category handler/shared') return mShared.matchesBlacklist( self.title.prefixedText, mw.loadData('Module:Category handler/blacklist') ) end end function CategoryHandler:isSuppressed() -- Find if categories are suppressed by either the arguments or by -- matching the blacklist. return self:isSuppressedByArguments() or not self:shouldSkipBlacklistCheck() and self:matchesBlacklist() end function CategoryHandler:getNamespaceParameters() if self._usesCurrentTitle then return self._data.currentTitleNamespaceParameters else if not mappings then mShared = mShared or require('Module:Category handler/shared') mappings = mShared.getParamMappings(true) -- gets mappings with mw.loadData end return mShared.getNamespaceParameters( self.title, mappings ) end end function CategoryHandler:namespaceParametersExist() -- Find whether any namespace parameters have been specified. -- We use the order "all" --> namespace params --> "other" as this is what -- the old template did. if self:parameter('all') then return true end if not mappings then mShared = mShared or require('Module:Category handler/shared') mappings = mShared.getParamMappings(true) -- gets mappings with mw.loadData end for ns, params in pairs(mappings) do for i, param in ipairs(params) do if self._args[param] then return true end end end if self:parameter('other') then return true end return false end function CategoryHandler:getCategories() local params = self:getNamespaceParameters() local nsCategory for i, param in ipairs(params) do local value = self._args[param] if value ~= nil then nsCategory = value break end end if nsCategory ~= nil or self:namespaceParametersExist() then -- Namespace parameters exist - advanced usage. if nsCategory == nil then nsCategory = self:parameter('other') end local ret = {self:parameter('all')} local numParam = tonumber(nsCategory) if numParam and numParam >= 1 and math.floor(numParam) == numParam then -- nsCategory is an integer ret[#ret + 1] = self._args[numParam] else ret[#ret + 1] = nsCategory end if #ret < 1 then return nil else return table.concat(ret) end elseif self._data.defaultNamespaces[self.title.namespace] then -- Namespace parameters don't exist, simple usage. return self._args[1] end return nil end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- Used for testing purposes. return { CategoryHandler = CategoryHandler } end function p._main(args, data) data = data or mw.loadData('Module:Category handler/data') local handler = CategoryHandler.new(data, args) if handler:isSuppressed() then return nil end return handler:getCategories() end function p.main(frame, data) data = data or mw.loadData('Module:Category handler/data') local args = require('Module:Arguments').getArgs(frame, { wrappers = data.wrappers, valueFunc = function (k, v) v = trimWhitespace(v) if type(k) == 'number' then if v ~= '' then return v else return nil end else return v end end }) return p._main(args, data) end return p b74dd63857b24904ac452429b11213f18647471f Шаблон:Documentation 10 39 57 2024-08-09T12:44:31Z DuOfOrl 5 Перенаправление на [[Шаблон:Doc]] wikitext text/x-wiki #REDIRECT [[Шаблон:Doc]] f1179db1364f4b0309c635b50e5682bfd279e109 Шаблон:Очищать кэш 10 55 83 2024-08-09T15:45:42Z DuOfOrl 5 Новая страница: «<includeonly><nowiki />{{#switch: {{lcfirst: {{{1|}}} }} | hourly | ежечасно = [[Категория:Анонпедия:Страницы с ежечасно очищаемым кэшем]] | daily | ежедневно | = [[Категория:Анонпедия:Страницы с ежедневно очищаемым кэшем]] | null edit | нулевой правкой = Категория:Анонпедия:Страницы с ежедневн...» wikitext text/x-wiki <includeonly><nowiki />{{#switch: {{lcfirst: {{{1|}}} }} | hourly | ежечасно = [[Категория:Анонпедия:Страницы с ежечасно очищаемым кэшем]] | daily | ежедневно | = [[Категория:Анонпедия:Страницы с ежедневно очищаемым кэшем]] | null edit | нулевой правкой = [[Категория:Анонпедия:Страницы с ежедневно совершаемой нулевой правкой]] | [[Категория:Анонпедия:Страницы c нераспознанным значением параметра шаблона «Очищать кэш»]] }}<nowiki /></includeonly><noinclude>{{doc}}</noinclude> 8f18e85d9593a7af672832dddcfc5c20eb8797a6 Модуль:Calendar 828 62 97 96 2024-08-09T15:56:44Z DuOfOrl 5 1 версия импортирована Scribunto text/plain local p = {} -- Необходимые модули и переменные local getArgs = require('Module:Arguments').getArgs local yesno = require('Module:Yesno') local mwlang = mw.getContentLanguage() local err = "―" -- NthDay nil result local tCon = table.concat -- 00) Блок многократно используемых списков local bool_to_number={ [true]=1, [false]=0 } local monthlang = {"января","февраля","марта","апреля","мая","июня","июля","августа","сентября","октября","ноября","декабря"} local month_to_num = {["января"]=1,["февраля"]=2,["марта"]=3,["апреля"]=4,["мая"]=5,["июня"]=6, ["июля"]=7,["августа"]=8,["сентября"]=9,["октября"]=10,["ноября"]=11,["декабря"]=12,["-"]=""} local monthd = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} local params = { {"г", "g"}, {"ю", "j"}} local comment = { '<span style="border-bottom: 1px dotted; cursor: help" title="по юлианскому календарю">','</span>'} -- duplicates: -- AST, BST, CST, ECT, IST, MST, PST, SST, local known_tzs = { ACDT='+10:30', ACST='+09:30', ACT ='+08:00', ADT ='-03:00', AEDT ='+11:00', AEST='+10:00', AFT ='+04:30', AKDT='-08:00', AKST ='-09:00', AMST ='+05:00', AMT ='+04:00', ART ='-03:00', AST ='+03:00', AST ='+04:00', AST ='+03:00', AST ='-04:00', AWDT='+09:00', AWST='+08:00', AZOST='-01:00', AZT ='+04:00', BDT ='+08:00', BIOT='+06:00', BIT ='-12:00', BOT ='-04:00', BRT ='-03:00', BST ='+06:00', BST ='+01:00', BTT ='+06:00', CAT ='+02:00', CCT ='+06:30', CDT ='-05:00', CEDT='+02:00', CEST='+02:00', CET ='+01:00', CHAST='+12:45', CIST='-08:00', CKT ='-10:00', CLST='-03:00', CLT ='-04:00', COST ='-04:00', COT ='-05:00', CST ='-06:00', CST ='+08:00', CVT ='-01:00', CXT ='+07:00', CHST='+10:00', DFT ='+01:00', EAST='-06:00', EAT ='+03:00', ECT ='-04:00', ECT ='-05:00', EDT ='-04:00', EEDT='+03:00', EEST ='+03:00', EET ='+02:00', EST ='-05:00', FJT ='+12:00', FKST='-03:00', FKT ='-04:00', GALT ='-06:00', GET ='+04:00', GFT ='-03:00', GILT='+12:00', GIT ='-09:00', GMT ='+00:00', GST ='-02:00', GYT ='-04:00', HADT='-09:00', HAST ='-10:00', HKT ='+08:00', HMT ='+05:00', HST ='-10:00', IRKT='+08:00', IRST ='+03:30', IST ='+05:30', IST ='+01:00', IST ='+02:00', JST ='+09:00', KRAT ='+07:00', KST ='+09:00', LHST='+10:30', LINT='+14:00', MAGT='+11:00', MDT ='-06:00', MIT ='-09:30', MSD ='+04:00', MSK ='+03:00', MST ='+08:00', MST ='-07:00', MST ='+06:30', MUT ='+04:00', NDT ='-02:30', NFT ='+11:30', NPT ='+05:45', NST ='-03:30', NT ='-03:30', OMST='+06:00', PDT ='-07:00', PETT ='+12:00', PHOT ='+13:00', PKT ='+05:00', PST ='-08:00', PST ='+08:00', RET ='+04:00', SAMT ='+04:00', SAST='+02:00', SBT ='+11:00', SCT ='+04:00', SLT ='+05:30', SST ='-11:00', SST ='+08:00', TAHT='-10:00', THA ='+07:00', UTC ='+00:00', UYST ='-02:00', UYT ='-03:00', VET ='-04:30', VLAT='+10:00', WAT ='+01:00', WEDT ='+01:00', WEST='+01:00', WET ='+00:00', YAKT='+09:00', YEKT ='+05:00', -- US Millitary (for RFC-822) Z='+00:00', A='-01:00', M='-12:00', N='+01:00', Y='+12:00', } local category = { ["no_parameters"]= "<!--[[Категория:Модуль:Calendar:Страницы без параметров]]-->", ["incomplete_parameters"]= "<!--[[Категория:Модуль:Calendar:Страницы с неполными или некорректными параметрами]]-->", ["without_verification"]= "<!--[[Категория:Модуль:Calendar:Страницы без проверки параметров]]-->", ["erroneous_parameters"]= "<!--[[Категория:Модуль:Calendar:Страницы с ошибочными параметрами]]-->" } -- несколько параметров передаются вместе с кодом ошибки в таблице, один может быть передан простым значением local e = { ["start"]="<span class=error>Ошибка: ", ["ending"]=".</span>", ["no_pattern_match"]="строка «%s» не совпадает с заданными паттернами", ["no_valid_date"]="дата «%s» не является корректной", ["wrong_jd"]="юлианская дата %s вне диапазона", ["no_data"]="нет входящих данных", ["too_many_arguments"]="ожидается менее %i аргументов", ["too_little_arguments"]="ожидается более %i аргументов", ["wrong_calculation"]="даты %s и %s не прошли проверку, %s дней разница", ["unknown_param"]="параметр %s неизвестен", ["unknown_error"]="неизвестная ошибка", ["tech_error"]="ошибка в функции %s", ["box_date"]="строка «%s» не является верной датой, пожалуйста, укажите дату в формате ГГГГ-ММ-ДД" -- [""]="", } local tzs_names = {"ACDT","ACST","ACT","ADT","AEDT","AEST","AFT","AKDT","AKST", "AMST","AMT","ART","AST","AST","AST","AST","AWDT","AWST","AZOST","AZT","BDT", "BIOT","BIT","BOT","BRT","BST","BST","BTT","CAT","CCT","CDT","CEDT","CEST", "CET","CHAST","CIST","CKT","CLST","CLT","COST","COT","CST","CST","CVT","CXT", "CHST","DFT","EAST","EAT","ECT","ECT","EDT","EEDT","EEST","EET","EST","FJT", "FKST","FKT","GALT","GET","GFT","GILT","GIT","GMT","GST","GYT","HADT","HAST", "HKT","HMT","HST","IRKT","IRST","IST","IST","IST","JST","KRAT","KST","LHST", "LINT","MAGT","MDT","MIT","MSD","MSK","MST","MST","MST","MUT","NDT","NFT", "NPT","NST","NT","OMST","PDT","PETT","PHOT","PKT","PST","PST","RET","SAMT", "SAST","SBT","SCT","SLT","SST","SST","TAHT","THA","UTC","UYST","UYT","VET", "VLAT","WAT","WEDT","WEST","WET","YAKT","YEKT","Z","A","M","N","Y","MSK"} local pattern = { -- для распознавания дат, переданных одним строчным параметром {"(-?%d%d%d%d?)[-%.%s/\\](%d%d)[-%.%s/\\](%d%d)", ["order"] = {3,2,1} }, -- yyyy mm dd {"(%d+)[-%.%s/\\](%d+)[-%.%s/\\](%d%d%d%d?)", ["order"] = {1,2,3} }, -- dd mm yyyy {"(%d%d)[-%.%s/\\](%d%d%d%d?)", ["order"] = {2,3} }, -- mm yyyy {"(%d%d%d%d?)[-%.%s/\\](%d%d)", ["order"] = {3,2} }, -- yyyy mm {"(%d+)%s(%l+)%s(%d%d%d%d?)", ["order"] = {1,2,3} }, -- d mmm y {"(%l+)%s(%d+),?%s(%d%d%d%d?)", ["order"] = {2,1,3} }, -- mmm d, y {"(%l+)%s(%d%d%d%d?)", ["order"] = {2,3} }, -- mmm y } local time_units = {"year","month","day"} --не используется --[[ local time_units = {"second", "minute", "hour", "day_of_month", "day_of_week", "day_of_year", "week", "month", "year", "year_of_century", "century"} ]]-- -- напоминание чтобы сделать более точные пересчёты - с часами / расчёт длительностей периодов local mnlang = {"ru_G", "ru_N", "en", "en_S", "de", "fr"} local month_lang = { ["ru_G"] = {"января","февраля","марта","апреля","мая","июня", "июля","августа","сентября","октября","ноября","декабря"}, ["ru_N"] = {"январь","февраль","март","апрель","май","июнь", "июль","август","сентябрь","октябрь","ноябрь","декабрь"}, ["en"] = {"january", "february", "march", "april", "may", "june", "july", "august", "september", "october", "november", "december"}, ["en_S"] = {"jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec"}, ["de"] = {"januar", "februar", "märz", "april", "mai", "juni", "juli", "august", "september", "oktober", "november", "dezember"}, ["fr"] = {"janvier", "février", "mars", "avril", "mai", "juin", "juillet", "août", "septembre", "octobre", "novembre", "décembre"} } -- заполняется автоматически local reverse_month_lang = {} -- вспомогательная функция для обращения таблиц (смена ключей со значениями) local reverse_table = function (strait_table) local reversed_table = {} for k,v in pairs(strait_table) do reversed_table[v] = k end return reversed_table end -- запуск цикла по заполнению обратных таблиц, необходимых для распознавания дат local filling_months = function (mnlang, month_lang) for i=1, #mnlang do reverse_month_lang[mnlang[i]] = reverse_table(month_lang[mnlang[i]]) end end -- 10) Блок общих функций local function trim(str) if not str then return nil else return str:match'^()%s*$' and '' or str:match'^%s*(.*%S)' end end local function purif(str) if str == "" or str == nil then return nil elseif type(tonumber(str)) == "number" then return math.floor(tonumber(str)) else return nil end -- need .5 -- ,5 number format converter? end local function is(str) if (not str) or (str == "") then return false else return yesno(str,false) end end local function init(num) local output = {} for i=1,num do table.insert(output, {["year"]="", ["month"]="", ["day"]=""}) end return unpack(output) end local function isyear(tbl) if type(tbl) ~= 'table' then return false elseif not tbl["year"] then return false elseif type(tbl["year"]) == 'number' then return true else return false end end local function inbord(val, down, up) return not (type(up) ~= "number" or type(down) ~= "number" or type(val) ~= "number" or up < down or val < down or val > up) end local function shallowcopy(orig) local orig_type = type(orig) local copy if orig_type == 'table' then copy = {} for orig_key, orig_value in pairs(orig) do copy[orig_key] = orig_value end else -- number, string, boolean, etc copy = orig end return copy end local inlist = function ( var, list ) local n = #list local inlist = false for i=1,n do if var == list[i] then inlist = true end end return inlist end -- 20) Блок общих проверочных функций, связанных с датами local function unwarp(tbl) if not tbl then return "" elseif type(tbl) ~= "table" then return tbl elseif (tbl.day or tbl.month or tbl.year) then return (tbl.year or "?").."-"..(tbl.month or "?").."-"..(tbl.day or "?") else return (tbl[3] or "?").."-"..(tbl[2] or "?").."-"..(tbl[1] or "?") end end local function leap_year(y,jul) if (not y) or (type(y) ~= "number") then return false elseif (y % 4) ~= 0 then return false elseif not jul and (y % 100 == 0 and y % 400 ~= 0) then return false else return true end end -- функция для вычисления последнего дня месяца для юлианского и григорианского календарей local function month_end_day (month,year,is_julian) local month_end_day = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} -- если не задан год, дата 29 февраля считается допустимой if not month or type(month) ~= "number" or month < 1 or month > 12 then return nil elseif month ~= 2 or not year then return month_end_day[month] elseif month == 2 and (year % 4) == 0 and not ((not is_julian) and (year % 100 == 0 and year % 400 ~= 0)) then return 29 elseif month == 2 then return 28 else return nil -- в случае не целого значения входящих параметров или при иных непредусмотренных событиях end end local function isdate ( chain , jul ) -- можно использовать для проверки таблиц с полями day, month, year if not chain then return false elseif (not type(chain) == "table") or (not inbord(chain.year,-9999,9999)) or (not inbord(chain.month,1,12)) or (not inbord(chain.day,1,31)) or chain.day > monthd[chain.month] -- or chain.year == 0 then return false elseif chain.month == 2 and chain.day == 29 and not leap_year(chain.year,jul) then return false else return true end -- check for other calendars needed? end local function ispartdate ( chain ) if not chain then return false elseif not (type(chain) == "table") then return false elseif (inbord(chain.year,-9999,9999) or inbord(chain.month,1,12) or inbord(chain.day,1,31)) then return true else return false end -- partial date -- more detailed check for 31.02.0000 needed -- check for other calendars needed end -- from date1 to date2 in one year (beetwen jan-dec, dec-jan needed) local function partdist(date1,date2) local mont, dist = 0, 0 local d1d, d1m, d2d, d2m = (date1["day"] or ""), (date1["month"] or ""),(date2["day"] or ""), (date2["month"] or "") if not (inbord(d1d,1,31) and inbord(d2d,1,31)) then return false end -- нужна доп. проверка частичных дат на корректность if (inbord(d1m,1,12) or inbord(d2m,1,12)) and (d1m == "" or d2m == "") then mont = purif(date1["month"] or date2["month"]) d1m, d2m = mont, mont end -- mw.log("📏 day: " ..d1d .."->"..d2d.." month: ".. d1m.."->"..d2m ) if (inbord(d1m,1,12) and d1d <= monthd[d1m]) and (inbord(d2m,1,12) and d2d <= monthd[d2m]) then if d2m == d1m then dist = d2d - d1d else dist = monthd[d1m] - d1d + d2d end return dist else return math.huge end end local function dmdist(d1,d2) local p1,p2 = math.huge,math.huge if not not partdist(d1,d2) then p1=partdist(d1,d2) end if not not partdist(d2,d1) then p1=partdist(d2,d1) end -- if (not p1) or (not p2) then -- return (p1 or "") .. (p2 or "") -- else -- mw.log("d1, d2 = " .. undate(d1) .. ", " .. undate(d2)) return math.min(tonumber(partdist(d1,d2)) or math.huge,tonumber(partdist(d2,d1)) or math.huge) -- end end -- 30) Блок функций для обработки ввода-вывода дат local function undate(tbl) if not tbl then return "" else return (tbl.year or "").."-"..(tbl.month or "").."-"..(tbl.day or "") end end -- функция для нормализации значений дат и перевода месяцев в числа local function numerize(str) if type(str) == "number" then return math.floor(str) elseif str == "" or str == nil or type(str) ~= "string" then return nil elseif type(tonumber(str)) == "number" then return math.floor(tonumber(str)) else for i=1, #mnlang do if inlist(mw.ustring.lower(str),month_lang[mnlang[i]]) then return reverse_month_lang[mnlang[i]][mw.ustring.lower(str)] end end end end -- функция распознавания даты, переданной одной строкой local function parse_date(date_string) if type(date_string) ~= "string" or date_string == "" then return nil end local out_date_str = {"","",""} local error_data = {} for i=1, #pattern do local result_1, result_2, result_3 = mw.ustring.match(mw.ustring.lower(date_string),pattern[i][1]) if (result_1 or "") > "" then out_date_str[pattern[i].order[1]] = result_1 out_date_str[pattern[i].order[2]] = result_2 if (pattern[i].order[3]) then out_date_str[pattern[i].order[3]] = result_3 end -- mw.log("Паттерн " .. i .. ", строка: " .. date_string) break end end local date = { ["day"] =numerize(out_date_str[1]), ["month"]=numerize(out_date_str[2]), ["year"] =numerize(out_date_str[3])} return date --, error_data end ----[[ УСТАРЕЛО ]]---- local numstr2date = function(numstr) local format = "Y-m-d" local iso_date = mwlang:formatDate(format,numstr) local y,m,d = string.match(iso_date, "(%d+)-(%d+)-(%d+)") local dateout = {["year"]=purif(y), ["month"]=purif(m), ["day"]=purif(d)} return dateout end --local numstr2date = function(numstr) -- local nums = {} -- local dateout = {} -- for num in string.gmatch(numstr,"(%d+)") do -- table.insert(nums,purif(num)) -- end -- if #nums ~= 3 then error("В поле даты вместо трёх чисел с разделителями указано " .. #nums) -- elseif not inbord(nums[2],1,12) then error("Месяц с номером " .. nums[2] .. " не найден") -- elseif not inbord(nums[3],1,31) then -- dateout = {["year"]=nums[3], ["month"]=nums[2], ["day"]=nums[1]} -- elseif not inbord(nums[1],1,31) then -- dateout = {["year"]=nums[1], ["month"]=nums[2], ["day"]=nums[3]} -- elseif inbord(nums[1],1,31) then -- dateout = {["year"]=nums[3], ["month"]=nums[2], ["day"]=nums[1]} -- else -- local mwlang = mw.getContentLanguage() -- implement mwlang:formatDate(format,datein,true) here -- return error("Не распознано " .. numstr .. " как дата") -- end -- return dateout --end local function year2lang(numyear,yearmark,wiki) if not numyear then return "" end if not yearmark then yearmark = "" end local output = "" local bcmark = " до н. э." if numyear > 0 then bcmark = "" else numyear = 1 - numyear end if wiki then -- output = tCon({'[[', numyear,' год',bcmark,'|', numyear,']]', " ", yearmark, " ", bcmark}) output = tCon({'[[', numyear,' год',bcmark,'|', trim(numyear .. " " .. yearmark .. " " .. bcmark), ']]'}) else output = tCon({numyear, " ", yearmark, bcmark}) end return trim(output) end local function day2lang(datein,wikidate,wiki,inner_brt) -- if not isdate(wikidate) then wiki = false end if not ispartdate(datein) then return "" end local dm_separ, output = "", nil if (not (not datein.day)) and (not (not datein.month)) then dm_separ = " " end if (not datein.month) then datein.month = "" end if (not datein.day) then datein.day = "" end local monlan = monthlang[datein.month] or "" if wiki and not inner_brt then output = tCon({"[[", wikidate.day, " ", monthlang[wikidate.month] or "", "|", (datein.day or ""), dm_separ, monlan, "]]"}) elseif wiki then output = tCon({"[[", wikidate.day, " ", monthlang[wikidate.month] or "", "|", (datein.day or ""), dm_separ, monlan}) else output = tCon({datein.day, dm_separ, monlan}) end return trim(output) end local function triple_txt2date(d,m,y) -- добавить (args[1]:match("(%a+)") or "-") для нестандартной записи -- mw.ustring.match((m or ""),"(%a+)") local msg = "" local year = purif((y or "-"):match("(%d+)")) local month = purif(month_to_num[string.lower(mw.ustring.match((m or ""),"(%a+)"))]) local day = purif((d or "-"):match("(%d+)")) if not month then msg = category.incomplete_parameters month = purif(month_to_num[string.lower(mw.ustring.match((d or ""),"(%a+)") or "-")]) end if (not day) and ((purif(string.match(m or "","(%d+)") or "") or 32) <= (monthd[month] or 31)) then msg = category.incomplete_parameters day = purif(m:match("(%d+)") or "") end if not year then msg = category.incomplete_parameters year = purif(string.match(m or "","(%d+)") or "") end local dateout = {["year"]=year, ["month"]=month, ["day"]=day, ["msg"]=msg} return dateout end local function glue(d1,m1,y1,d2,m2,y2) if (not d1) and (not m1) and (not y1) and (not d2) and (not m2) and (not y2) then return category.incomplete_parameters end local gd,gm,gy,jd,jm,jy = (d1 or ""), (m1 or ""), (y1 or ""), (d2 or ""), (m2 or ""), (y2 or "") --mw.log(tCon({gd,gm,gy,jd,jm,jy})) local gm_sep = {" [["," год|","]]"} if (not gy) or (gy == "") then gm_sep = {"","",""} end return tCon({comment[1],trim(trim(jd .. " " .. jm) .. " " .. jy ), comment[2]," ([[",trim(gd .. " " .. gm),"]]",gm_sep[1],(gy:match("(%d+)") or ""), gm_sep[2],gy,gm_sep[3],")",category.incomplete_parameters}) end -- добавить отображение без года local function double_couple(jdate, gdate, wd, wm, wy, sq_brts, yearmark) local msg = "" msg = (jdate.msg or "") .. (gdate.msg or "") local cd = {} local jd = shallowcopy(jdate) local gd = shallowcopy(gdate) local left = "(" local right = ")" if sq_brts then left = "&#091;" right = "&#093;" end if (not isdate(jdate,true)) then return error((jdate.day or "") .. "." .. (jdate.month or "") .."." .. (jdate.year or "") .. " неподходящая дата") elseif (not isdate(gdate)) then return error((gdate.day or "") .. "." .. (gdate.month or "") .."." .. (gdate.year or "") .. " неподходящая дата") end if jd.year == gd.year then cd.year = gd.year gd.year, jd.year = nil, nil end if jd.month == gd.month then cd.month = gd.month gd.month, jd.month = nil, nil end if (not not cd.month) and wm then return tCon({comment[1] .. trim(day2lang(jd,jdate,false) .. " " .. year2lang(jd.year,yearmark,false)) .. comment[2], trim(left .. day2lang(gd,gdate,wd,wm) .. " " .. year2lang(gd.year,yearmark,wy)) .. right, day2lang(cd,gdate,false) .. "]]", trim(year2lang(cd.year,yearmark,wy)..msg)}, " ") end return tCon({comment[1] .. trim(day2lang(jd,jdate,false) .. " " .. year2lang(jd.year,yearmark,false)) .. comment[2], trim(left .. day2lang(gd,gdate,wd) .. " " .. year2lang(gd.year,yearmark,wy)) .. right, trim(day2lang(cd,gdate,false)), trim(year2lang(cd.year,yearmark,wy)..msg)}, " ") end -- 40) Блок функций для перевода дат с использованием [[Юлианская дата]] local function gri2jd( datein ) if not isdate(datein) then return error((datein.day or "") .. "." .. (datein.month or "") .."." .. (datein.year or "") .. " неподходящая дата") end local year = datein.year local month = datein.month local day = datein.day -- jd calculation local a = math.floor((14 - month)/12) local y = year + 4800 - a local m = month + 12*a - 3 local offset = math.floor(y/4) - math.floor(y/100) + math.floor(y/400) - 32045 local jd = day + math.floor((153*m + 2)/5) + 365*y + offset -- jd validation local low, high = -1931076.5, 5373557.49999 if not (low <= jd and jd <= high) then return error((datein.day or "") .. "." .. (datein.month or "") .. "." .. (datein.year or "") .. " выходит за пределы разрешённого диапазона") end return jd end local function jd2jul( jd ) if type(jd) ~= "number" then return error("Промежуточная переменная " .. (jd or "") .. " не является числом") end -- calendar date calculation local c = jd + 32082 local d = math.floor((4*c + 3)/1461) local e = c - math.floor(1461*d/4) local m = math.floor((5*e + 2)/153) local year_out = d - 4800 + math.floor(m/10) local month_out = m + 3 - 12*math.floor(m/10) local day_out = e - math.floor((153*m + 2)/5) + 1 -- output local dateout = {["year"]=year_out, ["month"]=month_out, ["day"]=day_out} return dateout end local function jul2jd( datein ) if not isdate(datein,true) then return error((datein.day or "") .. "." .. (datein.month or "") ..".".. (datein.year or "") .. " неподходящая дата") end local year = datein.year local month = datein.month local day = datein.day -- jd calculation local a = math.floor((14 - month)/12) local y = year + 4800 - a local m = month + 12*a - 3 local offset = math.floor(y/4) - 32083 local jd = day + math.floor((153*m + 2)/5) + 365*y + offset -- jd validation local low, high = -1930999.5, 5373484.49999 if not (low <= jd and jd <= high) then return error((datein.day or "") .. "." .. (datein.month or "") .."." .. (datein.year or "") .. " выходит за пределы разрешённого диапазона") end return jd end local function jd2gri( jd ) if type(jd) ~= "number" then return error("Промежуточная переменная " .. (jd or "") .. " не является числом") end -- calendar date calculation local a = jd + 32044 local b = math.floor((4*a + 3) / 146097) local c = a - math.floor(146097*b/4) local d = math.floor((4*c+3)/1461) local e = c - math.floor(1461*d/4) local m = math.floor((5*e+2)/153) local day_out = e - math.floor((153*m+2)/5)+1 local month_out = m + 3 - 12*math.floor(m/10) local year_out = 100*b + d - 4800 + math.floor(m/10) -- output local dateout = {["year"]=year_out, ["month"]=month_out, ["day"]=day_out} return dateout end local function astroyear(num, bc) if not num then return error() elseif type(num) ~= "number" then return error() end if num < 1 then return num end if not bc then return num else return 1 - num end end local function recalc(datein,calend) if inlist(calend,params[1]) then return jd2jul(gri2jd(datein)), datein elseif inlist(calend,params[2]) then return datein, jd2gri(jul2jd(datein)) else error("Параметр " .. (calend or "") .. " не опознан, разрешённые: " .. tCon(params[1]," ") .. " и " .. tCon(params[2]," ")) end end -- 50) Функции для обработки UTC local function utc(str,margin) local d = 1 local dchar = "+" local beginning = "[[UTC" local ending = "]]" local cat = "" local nums = {} local hmarg, timedec = 0, 0 local mmarg = "00" local output = "" -- checking type of input if not margin then margin = 0 elseif type(tonumber(margin)) ~= 'number' then output = "Can't shift by " .. margin error(output) end if type(str) ~= 'string' then error("Нет входящей строки") elseif str:byte(1) == 43 then elseif inbord(str:byte(1),48,57) then cat = "[[Категория:Википедия:Ошибка в часовом поясе НП]]" elseif str:byte(1) == 45 or string.sub(str,1,3) == "−" or string.sub(str,1,1)=="-" then d = -1 else error(string.char(str:byte(1)) .. " недопустимый первый символ") end -- parsing input for num in string.gmatch(str,"(%d+)") do table.insert(nums,purif(num)) end if #nums > 2 then error("Ожидается всего 2 числа, а не " .. #nums) elseif #nums == 0 then error("Необходимо что-то ввести") elseif #nums == 1 then if inbord(nums[1],0,14) then timedec = d*nums[1] + margin else error("Только часы от -14 до 14") end elseif #nums == 2 then if not inbord(nums[1],0,14) then error("Только часы от -14 до 14") elseif not inbord(nums[2],0,59) then error("Минуты только от 0 до 59") else timedec = d*(nums[1] + nums[2]/60) + margin end end if tonumber(timedec) == purif(timedec) then hmarg = timedec else local h, m = math.modf(math.abs(timedec)) hmarg = h mmarg = math.floor(m*60) end if timedec == 0 then dchar = "±" elseif timedec > 0 then elseif timedec < 0 then dchar = "&minus;" end -- output output = beginning .. dchar .. math.abs(hmarg) .. ":" .. string.format("%02d",mmarg) .. ending .. cat return output end -- 60) Блок функций ввода-вывода function p.NthDay( frame ) local args = getArgs(frame, { frameOnly = true }) local num, wday, mont, yea, format = purif(args[1]), purif(args[2]), purif(args[3]), purif(args[4]), args[5] if not format then format = "%d.%m.%y" end if not inbord(num,-5,5) then return error("The number must be between -5 and 5") elseif num == 0 then return error("The number must not be zero") end if not inbord(wday,0,6) then return error("The day of the week must be between 0 and 6") end if not inbord(mont,1,12) then return error("The month must be between 1 and 12") end if not inbord(yea,0,9999) then return error("Wrong year number") end if inbord(num,1,5) then local m_start = os.time{year=yea, month=mont, day=1, hour=0} local m_wds = tonumber(os.date("%w", m_start)) local start_shift = ( (num - bool_to_number[wday >= m_wds]) * 7 - (m_wds - wday) ) * 24 * 60 * 60 local tim = m_start + start_shift if tonumber(os.date("%m", tim)) == mont then return (os.date(format, tim)) else return (err) end elseif inbord(num,-5,-1) then local m_end = os.time{year = yea, month = mont + 1, day = 1, hour = 0} - 24 * 60 * 60 local m_wde = tonumber(os.date("%w", m_end)) local end_shift = ((math.abs(num + 1) + bool_to_number[wday > m_wde]) * 7 + (m_wde - wday)) * 24 * 60 * 60 local tim = m_end - end_shift if tonumber(os.date("%m", tim)) == mont then return (os.date(format, tim)) else return (err) end end end -- =p.ToIso(mw.getCurrentFrame():newChild{title="smth",args={"12 декабря 2020"}}) -- =p.ToIso(mw.getCurrentFrame():newChild{title="smth",args={"1.2.1602"}}) -- =p.ToIso(mw.getCurrentFrame():newChild{title="smth",args={"12.12.2021"}}) -- =p.ToIso(mw.getCurrentFrame():newChild{title="smth",args={"2021.12.12"}}) function p.ToIso( frame ) local args = getArgs(frame, { frameOnly = true }) local datein = args[1] -- инициализация, заполнение обратных таблиц, копирование параметров filling_months(mnlang, month_lang) -- парсинг входящей даты по шаблону local date = parse_date(datein) if not (type(date.year) == 'number') then return ("Wrong year: " .. unwarp(date)) end if not (1 <= date.month and date.month <= 12) then return ("Wrong month: " .. unwarp(date)) end if not date.day or not (1 <= date.day and date.day <= month_end_day(date.month,date.year)) then return ("Wrong day: " .. unwarp(date)) end local timedate = os.time{year=date.year, month=date.month, day=date.day} local date = os.date("%Y-%m-%d", timedate) return date end -- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"12 декабря 2020"}}) -- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"1.2.1602"}}) -- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"декабрь 2020"}}) -- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"12-2020"}}) -- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"12.12.2021"}}) -- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"2021.12.12"}}) -- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"2021.11"}}) -- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"11.2021"}}) function p.BoxDate( frame ) local args = getArgs(frame, { frameOnly = true }) local txtDateIn, strFormat = args[1], args[2] local txtDateOut, date, status = p.bxDate(txtDateIn, strFormat, params) if status.brk then return error(status.errorText) else return txtDateOut end end function p.bxDate( txtDateIn , strFormat, params ) -- к отладке local txtDateOut, date, status = "", {}, {brk = false, errorCat = "", errorText = ""} strFormat = strFormat or "j xg Y" -- заглушка - таблица параметров на будущее params = params or {} if not txtDateIn then status.errorText = e.no_data status.errorCat = category.no_parameters status.brk = true else -- заполнение служебных таблиц filling_months(mnlang, month_lang) end if not status.brk then -- парсинг входящей даты по шаблону date = parse_date(txtDateIn) -- заменить сообщения об ошибках на списочные if not (date.year and type(date.year) == 'number') then status.errorText = string.format(e.box_date,txtDateIn) status.errorCat = category.incomplete_parameters status.brk = true end if not inbord(date.month,1,12) then status.errorText = string.format(e.box_date,txtDateIn) status.errorCat = category.incomplete_parameters status.brk = true end if not date.day and string.find(strFormat,"[dDjlNwzW]") then strFormat = trim(string.gsub(string.gsub(strFormat,"xg","F"),"[dDjlNwzW]","")) elseif not date.day then elseif not inbord(date.day,1,month_end_day(date.month,date.year)) then status.errorText = string.format(e.box_date,txtDateIn) status.errorCat = category.incomplete_parameters status.brk = true end end if not status.brk then txtDateOut = mwlang:formatDate(strFormat,tCon({date.year,date.month,date.day},"-"),true) end return txtDateOut, date, status end function p.ToDate( frame ) -- возможно неиспользуемая local args = getArgs(frame, { frameOnly = true }) local mwlang = mw.getContentLanguage() local datein = args[1] local format = "j xg Y" if not string.match(datein, "%p") then return datein elseif not args[2] then else format = args[2] end return mwlang:formatDate(format,datein,true) end -- =p.unitime(mw.getCurrentFrame():newChild{title="smth",args={"−1:30","1"}}) function p.unitime( frame ) local args = getArgs(frame, { frameOnly = true }) local DST = 0 if not args[2] then else DST = 1 end local utcin = "" local input = args[1] if not input then return "" end if inlist(input:upper(),tzs_names) then utcin = known_tzs[input:upper()] elseif (string.sub(input:upper(),1,3) == 'UTC') and (string.len(input) < 10) then utcin = string.sub(input,4) else if string.sub(input,1,1) == '[' or string.sub(input,1,1) == '{' or string.sub(input,1,1):upper() == 'U' or string.sub(input,1,1):upper() == 'M' then return input -- elseif not string.find(string.upper(string.sub(input,1,1)),"[\65-\90]") or -- not string.find(string.upper(string.sub(input,1,1)),"[\192-\223]") then -- return input else utcin = input end end -- elseif string.sub(input,1,3) ~= "−" then utcin = input -- or not (not input:find("[А-я]")) при наличии в строке юникода не работает local output = "" if DST == 0 then output = utc(utcin) else output = utc(utcin) .. ", [[летнее время|летом]] " .. utc(utcin,DST) end return output end -- УСТАРЕЛО -- =p.OldDate(mw.getCurrentFrame():newChild{title="smth",args={"20.02.2020","ю",["bc"]="1",["wd"]="1",["wy"]="1",["sq_brts"]="1",["yearmark"]="г."}}) function p.OldDate( frame ) local args = getArgs(frame, { frameOnly = true }) if not args[1] then return err end local gdate, jdate = {}, {} local strin = args[1] local cal = args[2]:lower() or "г" local bc = is(args["bc"]) local wd = is(args["wd"]) local wm = is(args["wm"]) local wy = is(args["wy"]) if not wd then wm = false end local sq_brts = is(args["sq_brts"]) local yearmark = "года" if yesno(args["yearmark"]) then elseif yesno(args["yearmark"]) == false then yearmark = "" else yearmark = trim(args["yearmark"]) or "года" end -- local infocard = is(args["infocard"]) -- local catName = args["catName"] or false local datein = numstr2date(strin) datein.year = astroyear(datein.year, bc) jdate, gdate = recalc(datein,cal) return double_couple(jdate, gdate, wd, wm, wy, sq_brts, yearmark) end -- =p.NewDate(mw.getCurrentFrame():newChild{title="Salt",args={"2020-02-20"}}) -- =p.NewDate(mw.getCurrentFrame():newChild{title="smth",args={"20.02.2020","ю",["bc"]="1",["wd"]="1",["wy"]="1",["sq_brts"]="1",["yearmark"]="г."}}) -- =p.NewDate(mw.getCurrentFrame():newChild{title="smth",args={"20.02.2020",["bc"]="0",["wd"]="1",["wy"]="1",["sq_brts"]="0",["yearmark"]=""}}) function p.NewDate( frame ) local args = getArgs(frame, { frameOnly = true }) if not args[1] then return err end local strin = args[1] local year, month, day if not not strin:match( "(-?%d%d%d%d%d)-(%d%d)-(%d%d)" ) then year, month, day = strin:match( "(-?%d%d%d%d%d)-(%d%d)-(%d%d)" ) elseif not not strin:match( "(-?%d+)-(%d+)-(%d+)" ) then year, month, day = strin:match( "(-?%d+)-(%d+)-(%d+)" ) elseif not not strin:match( "(%d%d)%.(%d%d)%.(-?%d%d%d%d%d)" ) then day, month, year = strin:match( "(%d%d)%.(%d%d)%.(-?%d%d%d%d%d)" ) elseif not not strin:match( "(%d+)%.(%d+)%.(-?%d+)" ) then day, month, year = strin:match( "(%d+)%.(%d+)%.(-?%d+)" ) end if not year then return error(args[1] .. " не подходит под форматы yyyy-mm-dd или dd.mm.yyyy") end local cal = "г" if (not args[2]) or (args[2] == "") then cal = "г" else cal = args[2]:lower() end local bc,wd,wm,wy,sq_brts = is(args["bc"]), is(args["wd"]), is(args["wd"]) and is(args["wm"]), is(args["wy"]), is(args["sq_brts"]) year = astroyear(purif(year),bc) local datein = {["year"]=purif(year), ["month"]=purif(month), ["day"]=purif(day)} local jdate, gdate = recalc(datein,cal) local yearmark = "года" local ym = args["yearmark"] or "" if yesno(ym) then elseif yesno(ym) == false then yearmark = "" else if not not ym:match("(%d+)") then error("Цифры в обозначении года: " .. ym) else yearmark = trim(ym) or "года" end end return double_couple(jdate, gdate, wd, wm, wy, sq_brts, yearmark) end -- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={}}) -- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"3","июня",nil,"21","мая"}}) -- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"28 августа","","1916 года","15"}}) -- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"3","июня","1900","21","мая"}}) -- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"6","июня","1889 год","25","мая"}}) -- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"28","ноября","1917","15"}}) -- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"28 августа","nil","1916 года","15"}}) -- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"4","января","1915","22","декабря","1914 года"}}) -- {{OldStyleDate|день (НС)|месяц (НС)|год (НС)|день (СС)|месяц (СС)|год (СС)}} function p.Test( frame ) local args = getArgs(frame, { frameOnly = true }) -- необходима проверка и замена nil на " " --[[mw.log((args[1] or "") .. " " .. (args[2] or "") .. " " .. (args[3] or "") .. " " .. (args[4] or "") .. " " .. (args[5] or "") .. " " .. (args[6] or "")) ]]-- local ingdate = triple_txt2date(args[1],args[2],args[3]) local injdate = triple_txt2date(args[4],args[5],args[6]) local j1date, g1date, j2date, g2date = init(4) mw.log("ingdate-".. (undate(ingdate) or "")) mw.log("injdate-".. (undate(injdate) or "")) local bc,wd,wm,wy,sq_brts,ny = is(args["bc"]), is(args["wd"]), is(args["wd"]) and is(args["wm"]), is(args["wy"]), is(args["sq_brts"]), is(args["ny"]) -- подавление формата для локальных тестов local wd, wm, wy = true, true, true local yearmark = "года" local ym = args["yearmark"] or ((mw.ustring.match((args[3] or ""),"(%a+)") or mw.ustring.match((args[6] or ""),"(%a+)")) or "") -- mw.log("ym " .. ym) if yesno(ym) then elseif yesno(ym) == false then yearmark = "" else if not not ym:match("(%d+)") then error("Цифры в обозначении года: " .. ym) else yearmark = trim(ym) or "года" end end if isdate(ingdate) or isdate(injdate) then if isdate(ingdate) then j1date, g1date = recalc(ingdate,"g") ingdate["full"] = true end if isdate(injdate) then j2date, g2date = recalc(injdate,"j") injdate["full"] = true end if ispartdate(ingdate) and ispartdate(injdate) then mw.log("📏 " .. dmdist(ingdate,injdate)) mw.log("📏 " .. dmdist(j1date,g1date)) mw.log("📏 " .. dmdist(j2date,g2date)) mw.log("📏 " .. dmdist(ingdate,g1date)) mw.log("📏 " .. dmdist(injdate,j2date)) end end if ny then if isyear(j1date) then else j1date["year"] = "" end if isyear(j2date) == nil then else j2date["year"] = "" end if isyear(g1date) == nil then else g1date["year"] = "" end if isyear(g2date) == nil then else g2date["year"] = "" end end if (isdate(j1date) and isdate(g1date) and isdate(j2date) and isdate(g2date)) then if ((j1date.year == j2date.year) and (j1date.month == j2date.month) and (j1date.day == j2date.day)) then return double_couple(j1date, g1date, wd, wm, wy, sq_brts, yearmark) else mw.log("📏 " .. (tostring(dmdist(ingdate,injdate)) or "")) return glue(args[1],args[2],args[3],args[4],args[5],args[6]) -- категория (предположительная разница в днях) и частичный вывод end elseif isdate(j1date) and isdate(g1date) then return double_couple(j1date, g1date, wd, wm, wy, sq_brts, yearmark) -- категория плюс частичная проверка elseif isdate(j2date) and isdate(g2date) then return double_couple(j2date, g2date, wd, wm, wy, sq_brts, yearmark) -- категория плюс частичная проверка elseif (ispartdate(ingdate) and ispartdate(injdate)) then mw.log("ingdate ".. (undate(ingdate) or "")) mw.log("injdate ".. (undate(injdate) or "")) mw.log("j1date " .. (undate(j1date ) or "")) mw.log("j2date " .. (undate(j2date ) or "")) mw.log("g1date " .. (undate(g1date ) or "")) mw.log("g2date " .. (undate(g2date ) or "")) mw.log("📏 " .. (tostring(partdist(ingdate,injdate)) or "").. " — " .. (tostring(partdist(injdate,ingdate)) or "")) return glue(args[1],args[2],args[3],args[4],args[5],args[6]) -- частичный или полный вывод, категория else mw.log("ingdate ".. (undate(ingdate) or "")) mw.log("injdate ".. (undate(injdate) or "")) mw.log("j1date " .. (undate(j1date ) or "")) mw.log("j2date " .. (undate(j2date ) or "")) mw.log("g1date " .. (undate(g1date ) or "")) mw.log("g2date " .. (undate(g2date ) or "")) return err .. category.incomplete_parameters end end return p a4a91f134ad3e3b246b3a6681a4ae438da766df4 Модуль:Message box/configuration 828 67 107 106 2024-08-09T16:02:48Z DuOfOrl 5 1 версия импортирована Scribunto text/plain -------------------------------------------------------------------------------- -- Message box configuration -- -- -- -- This module contains configuration data for [[Module:Message box]]. -- -------------------------------------------------------------------------------- return { ambox = { types = { speedy = { class = 'ambox-speedy', image = 'Ambox warning pn.svg' }, delete = { class = 'ambox-delete', image = 'Stop hand nuvola.svg' }, content = { class = 'ambox-content', image = 'Emblem-important.svg' }, style = { class = 'ambox-style', image = 'Broom_icon.svg' }, move = { class = 'ambox-move', image = 'Merge-split-transwiki default.svg' }, protection = { class = 'ambox-protection', image = 'Padlock-silver-medium.svg' }, notice = { class = 'ambox-notice', image = 'Information.svg' }, good = { class = 'ambox-good', image = 'Green star boxed.svg' }, serious = { class = 'ambox-serious', image = 'Stop hand nuvola.svg' }, merge = { class = 'ambox-merge', image = 'Merge-split-transwiki default.svg' }, discussion = { class = 'ambox-discussion', image = 'Nuvola apps ksirc.png' } }, default = 'notice', allowBlankParams = {'talk', 'sect', 'date', 'issue', 'fix', 'subst', 'hidden', 'image'}, allowSmall = true, smallParam = 'left', smallClass = 'mbox-small-left', substCheck = true, classes = {'metadata', 'ambox'}, imageEmptyCell = true, imageCheckBlank = true, imageSmallSize = '20x20px', imageCellDiv = true, useCollapsibleTextFields = true, imageRightNone = true, sectionDefault = 'статья', allowMainspaceCategories = true, templateCategory = 'Шаблоны:Шаблоны-сообщения для статей', templateCategoryRequireName = true, templateErrorCategory = 'Шаблоны:Шаблоны-сообщения для статей с пропущенными параметрами', templateErrorParamsToCheck = {'issue', 'fix'}, removalNotice = '[[Help:Maintenance template removal|Learn how and when to remove this template message]]', templatestyles = 'Module:Message box/ambox.css', }, cmbox = { types = { speedy = { class = 'cmbox-speedy notheme', image = 'Ambox warning pn.svg' }, delete = { class = 'cmbox-delete notheme', image = 'Ambox warning pn.svg' }, content = { class = 'cmbox-content notheme', image = 'Ambox important.svg' }, style = { class = 'cmbox-style notheme', image = 'Edit-clear.svg' }, move = { class = 'cmbox-move notheme', image = 'Merge-split-transwiki default.svg' }, protection = { class = 'cmbox-protection notheme', image = 'Padlock-silver-medium.svg' }, notice = { class = 'cmbox-notice notheme', image = 'Information icon4.svg' } }, default = 'notice', showInvalidTypeError = true, classes = {'cmbox'}, imageEmptyCell = true, useCollapsibleTextFields = true, templatestyles = 'Module:Message box/cmbox.css', }, fmbox = { types = { warning = { class = 'fmbox-warning', image = 'Ambox warning pn.svg' }, editnotice = { class = 'fmbox-editnotice', image = 'Information icon4.svg' }, system = { class = 'fmbox-system', image = 'Information icon4.svg' } }, default = 'system', showInvalidTypeError = true, classes = {'fmbox'}, imageEmptyCell = false, imageRightNone = false, useCollapsibleTextFields = true, templatestyles = 'Module:Message box/fmbox.css', }, imbox = { types = { speedy = { class = 'imbox-speedy', image = 'Ambox warning pn.svg' }, delete = { class = 'imbox-delete', image = 'Ambox warning pn.svg' }, content = { class = 'imbox-content', image = 'Ambox important.svg' }, style = { class = 'imbox-style', image = 'Edit-clear.svg' }, move = { class = 'imbox-move', image = 'Merge-split-transwiki default.svg' }, protection = { class = 'imbox-protection', image = 'Padlock-silver-medium.svg' }, license = { class = 'imbox-license licensetpl', image = 'Imbox license.png' -- @todo We need an SVG version of this }, featured = { class = 'imbox-featured', image = 'Cscr-featured.svg' }, notice = { class = 'imbox-notice', image = 'Information icon4.svg' } }, default = 'notice', showInvalidTypeError = true, classes = {'imbox'}, imageEmptyCell = true, below = true, useCollapsibleTextFields = true, templateCategory = 'Шаблоны:Шаблоны-сообщения для файлов', templatestyles = 'Module:Message box/imbox.css', }, ombox = { types = { speedy = { class = 'ombox-speedy', image = 'OOjs UI icon alert-destructive.svg' }, delete = { class = 'ombox-delete', image = 'OOjs UI icon alert-destructive.svg' }, content = { class = 'ombox-content', image = 'OOjs UI icon notice-warning.svg' }, style = { class = 'ombox-style', image = 'Edit-clear.svg' }, move = { class = 'ombox-move', image = 'Imbox move.png' }, protection = { class = 'ombox-protection', image = 'Imbox protection.png' }, notice = { class = 'ombox-notice', image = 'OOjs UI icon info-progressive.svg' } }, default = 'notice', showInvalidTypeError = true, classes = {'ombox'}, allowSmall = true, imageEmptyCell = true, imageRightNone = true, useCollapsibleTextFields = true, templatestyles = 'Module:Message box/ombox.css', }, tmbox = { types = { speedy = { class = 'tmbox-speedy notheme', image = 'Ambox warning pn.svg' }, delete = { class = 'tmbox-delete notheme', image = 'Ambox warning pn.svg' }, content = { class = 'tmbox-content notheme', image = 'Ambox important.svg' }, style = { class = 'tmbox-style notheme', image = 'Edit-clear.svg' }, move = { class = 'tmbox-move notheme', image = 'Merge-split-transwiki default.svg' }, protection = { class = 'tmbox-protection notheme', image = 'Padlock-silver-medium.svg' }, notice = { class = 'tmbox-notice notheme', image = 'Information icon4.svg' } }, default = 'notice', showInvalidTypeError = true, classes = {'tmbox'}, allowSmall = true, imageRightNone = true, imageEmptyCell = true, imageEmptyCellStyle = true, useCollapsibleTextFields = true, templateCategory = 'Шаблоны:Шаблоны-сообщения для страниц обсуждений', templatestyles = 'Module:Message box/tmbox.css', } } dd71cfc9b05d5244df926bfe86dfdb7ad0e0ff85 Модуль:Message box/ombox.css 828 68 109 108 2024-08-09T16:04:02Z DuOfOrl 5 1 версия импортирована sanitized-css text/css /* Скопировано из [[:en:Module:Message box/ombox.css]] */ .ombox { margin: 4px 0; border-collapse: collapse; border: 1px solid var(--border-color-base, #a2a9b1); /* Default "notice" gray */ background-color: var(--background-color-neutral-subtle, #f8f9fa); box-sizing: border-box; } /* For the "small=yes" option. */ .ombox.mbox-small { font-size: 88%; line-height: 1.25em; } .ombox-speedy { border: 2px solid var(--border-color-error, #b32424); /* Red */ background-color: var(--background-color-error-subtle, #fee7e6); /* Pink */ } .ombox-delete { border: 2px solid var(--background-color-error--active, #b32424); /* Red */ } .ombox-content { border: 1px solid #f28500; /* Orange */ } .ombox-style { border: 1px solid #fc3; /* Yellow */ } .ombox-move { border: 1px solid #9932cc; /* Purple */ } .ombox-protection { border: 2px solid var(--border-color-base, #a2a9b1); /* Gray-gold */ } .ombox .mbox-text { border: none; /* @noflip */ padding: 0.25em 0.9em; width: 100%; } .ombox .mbox-image { border: none; /* @noflip */ padding: 2px 0 2px 0.9em; text-align: center; } .ombox .mbox-imageright { border: none; /* @noflip */ padding: 2px 0.9em 2px 0; text-align: center; } /* An empty narrow cell */ .ombox .mbox-empty-cell { border: none; padding: 0; width: 1px; } .ombox .mbox-invalid-type { text-align: center; } /* Хак, TODO: посмотреть, как оно на самом деле работает */ .ombox .mbox-textsmall-div { font-size: 90%; } @media (min-width: 720px) { .ombox { margin: 4px 10%; } .ombox.mbox-small { /* @noflip */ clear: right; /* @noflip */ float: right; /* @noflip */ margin: 4px 0 4px 1em; width: 238px; } /* Стили нотификаций для ноутбуков */ @media (max-width: 1366px) { .ombox { margin-left: 6%; margin-right: 6%; } } } /* [[Категория:Модули:Подстраницы CSS]] */ 6627874170f6674674bfa5796b2f7dfb6698cd81 Модуль:Category handler/data 828 69 111 110 2024-08-09T16:05:04Z DuOfOrl 5 1 версия импортирована Scribunto text/plain -- This module assembles data to be passed to [[Module:Category handler]] using -- mw.loadData. This includes the configuration data and whether the current -- page matches the title blacklist. local data = require('Module:Category handler/config') local mShared = require('Module:Category handler/shared') local blacklist = require('Module:Category handler/blacklist') local title = mw.title.getCurrentTitle() data.currentTitleMatchesBlacklist = mShared.matchesBlacklist( title.prefixedText, blacklist ) data.currentTitleNamespaceParameters = mShared.getNamespaceParameters( title, mShared.getParamMappings() ) return data abbc68048ff698e88dda06b64ecf384bbf583120 Модуль:Category handler/config 828 70 113 112 2024-08-09T16:06:41Z DuOfOrl 5 1 версия импортирована Scribunto text/plain -------------------------------------------------------------------------------- -- [[Module:Category handler]] configuration data -- -- Language-specific parameter names and values can be set here. -- -- For blacklist config, see [[Module:Category handler/blacklist]]. -- -------------------------------------------------------------------------------- local cfg = {} -- Don't edit this line. -------------------------------------------------------------------------------- -- Start configuration data -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Parameter names -- -- These configuration items specify custom parameter names. -- -- To add one extra name, you can use this format: -- -- -- -- foo = 'parameter name', -- -- -- -- To add multiple names, you can use this format: -- -- -- -- foo = {'parameter name 1', 'parameter name 2', 'parameter name 3'}, -- -------------------------------------------------------------------------------- cfg.parameters = { -- The nocat and categories parameter suppress -- categorisation. They are used with Module:Yesno, and work as follows: -- -- cfg.nocat: -- Result of yesno() Effect -- true Categorisation is suppressed -- false Categorisation is allowed, and -- the blacklist check is skipped -- nil Categorisation is allowed -- -- cfg.categories: -- Result of yesno() Effect -- true Categorisation is allowed, and -- the blacklist check is skipped -- false Categorisation is suppressed -- nil Categorisation is allowed nocat = 'nocat', categories = 'categories', -- The parameter name for the legacy "category2" parameter. This skips the -- blacklist if set to the cfg.category2Yes value, and suppresses -- categorisation if present but equal to anything other than -- cfg.category2Yes or cfg.category2Negative. category2 = 'category2', -- cfg.subpage is the parameter name to specify how to behave on subpages. subpage = 'subpage', -- The parameter for data to return in all namespaces. all = 'all', -- The parameter name for data to return if no data is specified for the -- namespace that is detected. other = 'other', -- The parameter name used to specify a page other than the current page; -- used for testing and demonstration. demopage = 'page', } -------------------------------------------------------------------------------- -- Parameter values -- -- These are set values that can be used with certain parameters. Only one -- -- value can be specified, like this: -- -- -- -- cfg.foo = 'value name' -- -- -------------------------------------------------------------------------------- -- The following settings are used with the cfg.category2 parameter. Setting -- cfg.category2 to cfg.category2Yes skips the blacklist, and if cfg.category2 -- is present but equal to anything other than cfg.category2Yes or -- cfg.category2Negative then it supresses cateogrisation. cfg.category2Yes = 'yes' cfg.category2Negative = '¬' -- The following settings are used with the cfg.subpage parameter. -- cfg.subpageNo is the value to specify to not categorise on subpages; -- cfg.subpageOnly is the value to specify to only categorise on subpages. cfg.subpageNo = 'no' cfg.subpageOnly = 'only' -------------------------------------------------------------------------------- -- Default namespaces -- -- This is a table of namespaces to categorise by default. The keys are the -- -- namespace numbers. -- -------------------------------------------------------------------------------- cfg.defaultNamespaces = { [ 0] = true, -- main [ 6] = true, -- file [ 12] = true, -- help [ 14] = true, -- category [100] = true, -- portal [108] = true, -- book } -------------------------------------------------------------------------------- -- Wrappers -- -- This is a wrapper template or a list of wrapper templates to be passed to -- -- [[Module:Arguments]]. -- -------------------------------------------------------------------------------- cfg.wrappers = 'Template:Category handler' -------------------------------------------------------------------------------- -- End configuration data -- -------------------------------------------------------------------------------- return cfg -- Don't edit this line. 373cd107b13a5b00e6a1b7e66a749f12502c849d Шаблон:Tag 10 72 117 116 2024-08-09T16:09:01Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{#ifeq: {{{style|}}} | regular | <templatestyles src="Модуль:Template call code/styles.css" /> }}<{{#ifeq: {{{style|}}} | regular | span | code }} class="{{#ifeq: {{{wrap|}}} | yes | wrap | nowrap }}" style="{{#switch: {{{style|}}} | plain = border:none; background:transparent; | regular = | {{{style|}}} }}"><!-- Opening tag -->{{#switch: {{#if: {{{2|}}} | {{{2|}}} | pair }} |c|close = |s|single |o|open |p|pair = {{#ifeq: {{{1|tag}}} | !-- | {{#ifeq: {{{style|}}} | regular | <span class="ts-templateCallCode-weak">&lt;!--</span> | &lt;!-- }} | {{#ifeq: {{{style|}}} | regular | <span class="ts-templateCallCode-weak">&lt;</span> | &lt; }}{{{1|tag}}}{{#if: {{{params|{{{p|}}}}}} | &#32;{{{params|{{{p|}}}}}} }} }} }}<!-- Content between tags -->{{#switch: {{#if: {{{2|}}} | {{{2|}}} | pair }} |c|close = {{{content|{{{c|}}}}}} |s|single = &#32;{{#ifeq: {{{style|}}} | regular | <span class="ts-templateCallCode-weak">/&gt;</span> | /&gt; }} |o|open = {{#ifeq: {{{style|}}} | regular | <span class="ts-templateCallCode-weak">&gt;</span> | &gt; }}{{{content|{{{c|}}}}}} |p|pair = {{#ifeq: {{{1|tag}}} | !-- || {{#ifeq: {{{style|}}} | regular | <span class="ts-templateCallCode-weak">&gt;</span> | &gt; }} }}{{{content|{{{c|}}}}}} }}<!-- Closing tag -->{{#switch: {{#if: {{{2|}}} | {{{2|}}} | pair }} |s|single |o|open = |c|close |p|pair = {{#ifeq: {{{1|tag}}} | !-- | {{#ifeq: {{{style|}}} | regular | <span class="ts-templateCallCode-weak">--&gt;</span> | --&gt; }} | {{#ifeq: {{{style|}}} | regular | <span class="ts-templateCallCode-weak">&lt;/</span>{{{1|tag}}}<span class="ts-templateCallCode-weak">&gt;</span> | &lt;/{{{1|tag}}}&gt; }} }} }}<!-- --></{{#ifeq: {{{style|}}} | regular | span | code }}><noinclude>{{doc}}</noinclude> 2818843691a5275eaf013ee7cc1ac4b87c34f392 Шаблон:Big 10 73 119 118 2024-08-09T16:10:05Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <span style="font-size:120%;">{{{1}}}</span><noinclude> {{documentation}} <!-- PLEASE ADD CATEGORIES TO THE /doc SUBPAGE, THANKS --> </noinclude> 233a0192f59d7a0c6fef6b818e8d1c96d48295d2 Модуль:Category handler/shared 828 74 121 120 2024-08-09T16:14:00Z DuOfOrl 5 1 версия импортирована Scribunto text/plain -- This module contains shared functions used by [[Module:Category handler]] -- and its submodules. local p = {} function p.matchesBlacklist(page, blacklist) for i, pattern in ipairs(blacklist) do local match = mw.ustring.match(page, pattern) if match then return true end end return false end function p.getParamMappings(useLoadData) local dataPage = 'Module:Namespace detect/data' if useLoadData then return mw.loadData(dataPage).mappings else return require(dataPage).mappings end end function p.getNamespaceParameters(titleObj, mappings) -- We don't use title.nsText for the namespace name because it adds -- underscores. local mappingsKey if titleObj.isTalkPage then mappingsKey = 'talk' else mappingsKey = mw.site.namespaces[titleObj.namespace].name end mappingsKey = mw.ustring.lower(mappingsKey) return mappings[mappingsKey] or {} end return p d2d5de1a031e6ce97c242cbfa8afe7a92cb9eca5 Модуль:Category handler/blacklist 828 75 123 122 2024-08-09T16:16:12Z DuOfOrl 5 1 версия импортирована Scribunto text/plain -- This module contains the blacklist used by [[Module:Category handler]]. -- Pages that match Lua patterns in this list will not be categorised unless -- categorisation is explicitly requested. return { '^Main Page$', -- don't categorise the main page. -- Don't categorise the following pages or their subpages. -- "%f[/\0]" matches if the next character is "/" or the end of the string. '^Wikipedia:Cascade%-protected items%f[/\0]', '^User:UBX%f[/\0]', -- The userbox "template" space. '^User talk:UBX%f[/\0]', -- Don't categorise subpages of these pages, but allow -- categorisation of the base page. '^Wikipedia:Template messages/.*$', '/[aA]rchive' -- Don't categorise archives. } c84948ad9808d5d323408d5d10d5652f748a0550 Модуль:Namespace detect/data 828 76 125 124 2024-08-09T16:32:35Z DuOfOrl 5 1 версия импортирована Scribunto text/plain -------------------------------------------------------------------------------- -- Namespace detect data -- -- This module holds data for [[Module:Namespace detect]] to be loaded per -- -- page, rather than per #invoke, for performance reasons. -- -------------------------------------------------------------------------------- local cfg = require('Module:Namespace detect/config') local function addKey(t, key, defaultKey) if key ~= defaultKey then t[#t + 1] = key end end -- Get a table of parameters to query for each default parameter name. -- This allows wikis to customise parameter names in the cfg table while -- ensuring that default parameter names will always work. The cfg table -- values can be added as a string, or as an array of strings. local defaultKeys = { 'main', 'talk', 'other', 'subjectns', 'demospace', 'demopage' } local argKeys = {} for i, defaultKey in ipairs(defaultKeys) do argKeys[defaultKey] = {defaultKey} end for defaultKey, t in pairs(argKeys) do local cfgValue = cfg[defaultKey] local cfgValueType = type(cfgValue) if cfgValueType == 'string' then addKey(t, cfgValue, defaultKey) elseif cfgValueType == 'table' then for i, key in ipairs(cfgValue) do addKey(t, key, defaultKey) end end cfg[defaultKey] = nil -- Free the cfg value as we don't need it any more. end local function getParamMappings() --[[ -- Returns a table of how parameter names map to namespace names. The keys -- are the actual namespace names, in lower case, and the values are the -- possible parameter names for that namespace, also in lower case. The -- table entries are structured like this: -- { -- [''] = {'main'}, -- ['wikipedia'] = {'wikipedia', 'project', 'wp'}, -- ... -- } --]] local mappings = {} local mainNsName = mw.site.subjectNamespaces[0].name mainNsName = mw.ustring.lower(mainNsName) mappings[mainNsName] = mw.clone(argKeys.main) mappings['talk'] = mw.clone(argKeys.talk) for nsid, ns in pairs(mw.site.subjectNamespaces) do if nsid ~= 0 then -- Exclude main namespace. local nsname = mw.ustring.lower(ns.name) local canonicalName = mw.ustring.lower(ns.canonicalName) mappings[nsname] = {nsname} if canonicalName ~= nsname then table.insert(mappings[nsname], canonicalName) end for _, alias in ipairs(ns.aliases) do table.insert(mappings[nsname], mw.ustring.lower(alias)) end end end return mappings end return { argKeys = argKeys, cfg = cfg, mappings = getParamMappings() } d224f42a258bc308ef3ad8cc8686cd7a4f47d005 Модуль:Namespace detect/config 828 77 127 126 2024-08-09T16:45:33Z DuOfOrl 5 1 версия импортирована Scribunto text/plain -------------------------------------------------------------------------------- -- Namespace detect configuration data -- -- -- -- This module stores configuration data for Module:Namespace detect. Here -- -- you can localise the module to your wiki's language. -- -- -- -- To activate a configuration item, you need to uncomment it. This means -- -- that you need to remove the text "-- " at the start of the line. -- -------------------------------------------------------------------------------- local cfg = {} -- Don't edit this line. -------------------------------------------------------------------------------- -- Parameter names -- -- These configuration items specify custom parameter names. Values added -- -- here will work in addition to the default English parameter names. -- -- To add one extra name, you can use this format: -- -- -- -- cfg.foo = 'parameter name' -- -- -- -- To add multiple names, you can use this format: -- -- -- -- cfg.foo = {'parameter name 1', 'parameter name 2', 'parameter name 3'} -- -------------------------------------------------------------------------------- ---- This parameter displays content for the main namespace: -- cfg.main = 'main' ---- This parameter displays in talk namespaces: -- cfg.talk = 'talk' ---- This parameter displays content for "other" namespaces (namespaces for which ---- parameters have not been specified): -- cfg.other = 'other' ---- This parameter makes talk pages behave as though they are the corresponding ---- subject namespace. Note that this parameter is used with [[Module:Yesno]]. ---- Edit that module to change the default values of "yes", "no", etc. -- cfg.subjectns = 'subjectns' ---- This parameter sets a demonstration namespace: -- cfg.demospace = 'demospace' ---- This parameter sets a specific page to compare: cfg.demopage = 'page' -------------------------------------------------------------------------------- -- Table configuration -- -- These configuration items allow customisation of the "table" function, -- -- used to generate a table of possible parameters in the module -- -- documentation. -- -------------------------------------------------------------------------------- ---- The header for the namespace column in the wikitable containing the list of ---- possible subject-space parameters. -- cfg.wikitableNamespaceHeader = 'Namespace' ---- The header for the wikitable containing the list of possible subject-space ---- parameters. -- cfg.wikitableAliasesHeader = 'Aliases' -------------------------------------------------------------------------------- -- End of configuration data -- -------------------------------------------------------------------------------- return cfg -- Don't edit this line. 0e4ff08d13c4b664d66b32c232deb129b77c1a56 Модуль:Citation/CS1 828 78 129 128 2024-08-09T16:53:51Z DuOfOrl 5 1 версия импортирована Scribunto text/plain require ('strict'); --[[--------------------------< F O R W A R D D E C L A R A T I O N S >-------------------------------------- each of these counts against the Lua upvalue limit ]] local validation; -- functions in Module:Citation/CS1/Date_validation local utilities; -- functions in Module:Citation/CS1/Utilities local z = {}; -- table of tables in Module:Citation/CS1/Utilities local identifiers; -- functions and tables in Module:Citation/CS1/Identifiers local metadata; -- functions in Module:Citation/CS1/COinS local cfg = {}; -- table of configuration tables that are defined in Module:Citation/CS1/Configuration local whitelist = {}; -- table of tables listing valid template parameter names; defined in Module:Citation/CS1/Whitelist local boxDate = require('Module:Calendar').bxDate; -- РУВИКИ: все даты делаем человекочитаемыми --[[------------------< P A G E S C O P E V A R I A B L E S >--------------- declare variables here that have page-wide scope that are not brought in from other modules; that are created here and used here ]] local added_deprecated_cat; -- Boolean flag so that the category is added only once local added_vanc_errs; -- Boolean flag so we only emit one Vancouver error / category local added_generic_name_errs; -- Boolean flag so we only emit one generic name error / category and stop testing names once an error is encountered local added_numeric_name_errs; -- Boolean flag so we only emit one numeric name error / category and stop testing names once an error is encountered local added_numeric_name_maint; -- Boolean flag so we only emit one numeric name maint category and stop testing names once a category has been emitted local Frame; -- holds the module's frame table local is_preview_mode; -- true when article is in preview mode; false when using 'Preview page with this template' (previewing the module) local is_sandbox; -- true when using sandbox modules to render citation --[[--------------------------< F I R S T _ S E T >------------------------------------------------------------ Locates and returns the first set value in a table of values where the order established in the table, left-to-right (or top-to-bottom), is the order in which the values are evaluated. Returns nil if none are set. This version replaces the original 'for _, val in pairs do' and a similar version that used ipairs. With the pairs version the order of evaluation could not be guaranteed. With the ipairs version, a nil value would terminate the for-loop before it reached the actual end of the list. ]] local function first_set (list, count) local i = 1; while i <= count do -- loop through all items in list if utilities.is_set( list[i] ) then return list[i]; -- return the first set list member end i = i + 1; -- point to next end end --[[--------------------------< A D D _ V A N C _ E R R O R >---------------------------------------------------- Adds a single Vancouver system error message to the template's output regardless of how many error actually exist. To prevent duplication, added_vanc_errs is nil until an error message is emitted. added_vanc_errs is a Boolean declared in page scope variables above ]] local function add_vanc_error (source, position) if added_vanc_errs then return end added_vanc_errs = true; -- note that we've added this category utilities.set_message ('err_vancouver', {source, position}); end --[[--------------------------< I S _ S C H E M E >------------------------------------------------------------ does this thing that purports to be a URI scheme seem to be a valid scheme? The scheme is checked to see if it is in agreement with http://tools.ietf.org/html/std66#section-3.1 which says: Scheme names consist of a sequence of characters beginning with a letter and followed by any combination of letters, digits, plus ("+"), period ("."), or hyphen ("-"). returns true if it does, else false ]] local function is_scheme (scheme) return scheme and scheme:match ('^%a[%a%d%+%.%-]*:'); -- true if scheme is set and matches the pattern end --[=[-------------------------< I S _ D O M A I N _ N A M E >-------------------------------------------------- Does this thing that purports to be a domain name seem to be a valid domain name? Syntax defined here: http://tools.ietf.org/html/rfc1034#section-3.5 BNF defined here: https://tools.ietf.org/html/rfc4234 Single character names are generally reserved; see https://tools.ietf.org/html/draft-ietf-dnsind-iana-dns-01#page-15; see also [[Single-letter second-level domain]] list of TLDs: https://www.iana.org/domains/root/db RFC 952 (modified by RFC 1123) requires the first and last character of a hostname to be a letter or a digit. Between the first and last characters the name may use letters, digits, and the hyphen. Also allowed are IPv4 addresses. IPv6 not supported domain is expected to be stripped of any path so that the last character in the last character of the TLD. tld is two or more alpha characters. Any preceding '//' (from splitting a URL with a scheme) will be stripped here. Perhaps not necessary but retained in case it is necessary for IPv4 dot decimal. There are several tests: the first character of the whole domain name including subdomains must be a letter or a digit internationalized domain name (ASCII characters with .xn-- ASCII Compatible Encoding (ACE) prefix xn-- in the TLD) see https://tools.ietf.org/html/rfc3490 single-letter/digit second-level domains in the .org, .cash, and .today TLDs q, x, and z SL domains in the .com TLD i and q SL domains in the .net TLD single-letter SL domains in the ccTLDs (where the ccTLD is two letters) two-character SL domains in gTLDs (where the gTLD is two or more letters) three-plus-character SL domains in gTLDs (where the gTLD is two or more letters) IPv4 dot-decimal address format; TLD not allowed returns true if domain appears to be a proper name and TLD or IPv4 address, else false ]=] local function is_domain_name (domain) if not domain then return false; -- if not set, abandon end domain = domain:gsub ('^//', ''); -- strip '//' from domain name if present; done here so we only have to do it once if not domain:match ('^[%w]') then -- first character must be letter or digit return false; end if domain:match ('^%a+:') then -- hack to detect things that look like s:Page:Title where Page: is namespace at Wikisource return false; end local patterns = { -- patterns that look like URLs '%f[%w][%w][%w%-]+[%w]%.%a%a+$', -- three or more character hostname.hostname or hostname.tld '%f[%w][%w][%w%-]+[%w]%.xn%-%-[%w]+$', -- internationalized domain name with ACE prefix '%f[%a][qxz]%.com$', -- assigned one character .com hostname (x.com times out 2015-12-10) '%f[%a][iq]%.net$', -- assigned one character .net hostname (q.net registered but not active 2015-12-10) '%f[%w][%w]%.%a%a$', -- one character hostname and ccTLD (2 chars) '%f[%w][%w][%w]%.%a%a+$', -- two character hostname and TLD '^%d%d?%d?%.%d%d?%d?%.%d%d?%d?%.%d%d?%d?', -- IPv4 address } for _, pattern in ipairs (patterns) do -- loop through the patterns list if domain:match (pattern) then return true; -- if a match then we think that this thing that purports to be a URL is a URL end end for _, d in ipairs (cfg.single_letter_2nd_lvl_domains_t) do -- look for single letter second level domain names for these top level domains if domain:match ('%f[%w][%w]%.' .. d) then return true end end return false; -- no matches, we don't know what this thing is end --[[--------------------------< I S _ U R L >------------------------------------------------------------------ returns true if the scheme and domain parts of a URL appear to be a valid URL; else false. This function is the last step in the validation process. This function is separate because there are cases that are not covered by split_url(), for example is_parameter_ext_wikilink() which is looking for bracketted external wikilinks. ]] local function is_url (scheme, domain) if utilities.is_set (scheme) then -- if scheme is set check it and domain return is_scheme (scheme) and is_domain_name (domain); else return is_domain_name (domain); -- scheme not set when URL is protocol-relative end end --[[--------------------------< S P L I T _ U R L >------------------------------------------------------------ Split a URL into a scheme, authority indicator, and domain. First remove Fully Qualified Domain Name terminator (a dot following TLD) (if any) and any path(/), query(?) or fragment(#). If protocol-relative URL, return nil scheme and domain else return nil for both scheme and domain. When not protocol-relative, get scheme, authority indicator, and domain. If there is an authority indicator (one or more '/' characters immediately following the scheme's colon), make sure that there are only 2. Any URL that does not have news: scheme must have authority indicator (//). TODO: are there other common schemes like news: that don't use authority indicator? Strip off any port and path; ]] local function split_url (url_str) local scheme, authority, domain; url_str = url_str:gsub ('([%a%d])%.?[/%?#].*$', '%1'); -- strip FQDN terminator and path(/), query(?), fragment (#) (the capture prevents false replacement of '//') if url_str:match ('^//%S*') then -- if there is what appears to be a protocol-relative URL domain = url_str:match ('^//(%S*)') elseif url_str:match ('%S-:/*%S+') then -- if there is what appears to be a scheme, optional authority indicator, and domain name scheme, authority, domain = url_str:match ('(%S-:)(/*)(%S+)'); -- extract the scheme, authority indicator, and domain portions if utilities.is_set (authority) then authority = authority:gsub ('//', '', 1); -- replace place 1 pair of '/' with nothing; if utilities.is_set(authority) then -- if anything left (1 or 3+ '/' where authority should be) then return scheme; -- return scheme only making domain nil which will cause an error message end else if not scheme:match ('^news:') then -- except for news:..., MediaWiki won't link URLs that do not have authority indicator; TODO: a better way to do this test? return scheme; -- return scheme only making domain nil which will cause an error message end end domain = domain:gsub ('(%a):%d+', '%1'); -- strip port number if present end return scheme, domain; end --[[--------------------------< L I N K _ P A R A M _ O K >--------------------------------------------------- checks the content of |title-link=, |series-link=, |author-link=, etc. for properly formatted content: no wikilinks, no URLs Link parameters are to hold the title of a Wikipedia article, so none of the WP:TITLESPECIALCHARACTERS are allowed: # < > [ ] | { } _ except the underscore which is used as a space in wiki URLs and # which is used for section links returns false when the value contains any of these characters. When there are no illegal characters, this function returns TRUE if value DOES NOT appear to be a valid URL (the |<param>-link= parameter is ok); else false when value appears to be a valid URL (the |<param>-link= parameter is NOT ok). ]] local function link_param_ok (value) local scheme, domain; if value:find ('[<>%[%]|{}]') then -- if any prohibited characters return false; end scheme, domain = split_url (value); -- get scheme or nil and domain or nil from URL; return not is_url (scheme, domain); -- return true if value DOES NOT appear to be a valid URL end --[[--------------------------< L I N K _ T I T L E _ O K >--------------------------------------------------- Use link_param_ok() to validate |<param>-link= value and its matching |<title>= value. |<title>= may be wiki-linked but not when |<param>-link= has a value. This function emits an error message when that condition exists check <link> for inter-language interwiki-link prefix. prefix must be a MediaWiki-recognized language code and must begin with a colon. ]] local function link_title_ok (link, lorig, title, torig) local orig; if utilities.is_set (link) then -- don't bother if <param>-link doesn't have a value if not link_param_ok (link) then -- check |<param>-link= markup orig = lorig; -- identify the failing link parameter elseif title:find ('%[%[') then -- check |title= for wikilink markup orig = torig; -- identify the failing |title= parameter elseif link:match ('^%a+:') then -- if the link is what looks like an interwiki local prefix = link:match ('^(%a+):'):lower(); -- get the interwiki prefix if cfg.inter_wiki_map[prefix] then -- if prefix is in the map, must have preceding colon orig = lorig; -- flag as error end end end if utilities.is_set (orig) then link = ''; -- unset utilities.set_message ('err_bad_paramlink', orig); -- URL or wikilink in |title= with |title-link=; end return link; -- link if ok, empty string else end --[[--------------------------< C H E C K _ U R L >------------------------------------------------------------ Determines whether a URL string appears to be valid. First we test for space characters. If any are found, return false. Then split the URL into scheme and domain portions, or for protocol-relative (//example.com) URLs, just the domain. Use is_url() to validate the two portions of the URL. If both are valid, or for protocol-relative if domain is valid, return true, else false. Because it is different from a standard URL, and because this module used external_link() to make external links that work for standard and news: links, we validate newsgroup names here. The specification for a newsgroup name is at https://tools.ietf.org/html/rfc5536#section-3.1.4 ]] local function check_url( url_str ) if nil == url_str:match ("^%S+$") then -- if there are any spaces in |url=value it can't be a proper URL return false; end local scheme, domain; scheme, domain = split_url (url_str); -- get scheme or nil and domain or nil from URL; if 'news:' == scheme then -- special case for newsgroups return domain:match('^[%a%d%+%-_]+%.[%a%d%+%-_%.]*[%a%d%+%-_]$'); end return is_url (scheme, domain); -- return true if value appears to be a valid URL end --[=[-------------------------< I S _ P A R A M E T E R _ E X T _ W I K I L I N K >---------------------------- Return true if a parameter value has a string that begins and ends with square brackets [ and ] and the first non-space characters following the opening bracket appear to be a URL. The test will also find external wikilinks that use protocol-relative URLs. Also finds bare URLs. The frontier pattern prevents a match on interwiki-links which are similar to scheme:path URLs. The tests that find bracketed URLs are required because the parameters that call this test (currently |title=, |chapter=, |work=, and |publisher=) may have wikilinks and there are articles or redirects like '//Hus' so, while uncommon, |title=[[//Hus]] is possible as might be [[en://Hus]]. ]=] local function is_parameter_ext_wikilink (value) local scheme, domain; if value:match ('%f[%[]%[%a%S*:%S+.*%]') then -- if ext. wikilink with scheme and domain: [xxxx://yyyyy.zzz] scheme, domain = split_url (value:match ('%f[%[]%[(%a%S*:%S+).*%]')); elseif value:match ('%f[%[]%[//%S+.*%]') then -- if protocol-relative ext. wikilink: [//yyyyy.zzz] scheme, domain = split_url (value:match ('%f[%[]%[(//%S+).*%]')); elseif value:match ('%a%S*:%S+') then -- if bare URL with scheme; may have leading or trailing plain text scheme, domain = split_url (value:match ('(%a%S*:%S+)')); elseif value:match ('//%S+') then -- if protocol-relative bare URL: //yyyyy.zzz; may have leading or trailing plain text scheme, domain = split_url (value:match ('(//%S+)')); -- what is left should be the domain else return false; -- didn't find anything that is obviously a URL end return is_url (scheme, domain); -- return true if value appears to be a valid URL end --[[-------------------------< C H E C K _ F O R _ U R L >----------------------------------------------------- loop through a list of parameters and their values. Look at the value and if it has an external link, emit an error message. ]] local function check_for_url (parameter_list, error_list) for k, v in pairs (parameter_list) do -- for each parameter in the list if is_parameter_ext_wikilink (v) then -- look at the value; if there is a URL add an error message table.insert (error_list, utilities.wrap_style ('parameter', k)); end end end --[[--------------------------< S A F E _ F O R _ U R L >------------------------------------------------------ Escape sequences for content that will be used for URL descriptions ]] local function safe_for_url( str ) if str:match( "%[%[.-%]%]" ) ~= nil then utilities.set_message ('err_wikilink_in_url', {}); end return str:gsub( '[%[%]\n]', { ['['] = '&#91;', [']'] = '&#93;', ['\n'] = ' ' } ); end --[[--------------------------< E X T E R N A L _ L I N K >---------------------------------------------------- Format an external link with error checking ]] local function external_link (URL, label, source, access) local err_msg = ''; local domain; local path; local base_url; if not utilities.is_set (label) then label = URL; if utilities.is_set (source) then utilities.set_message ('err_bare_url_missing_title', {utilities.wrap_style ('parameter', source)}); else error (cfg.messages["bare_url_no_origin"]); -- programmer error; valid parameter name does not have matching meta-parameter end end if not check_url (URL) then utilities.set_message ('err_bad_url', {utilities.wrap_style ('parameter', source)}); end domain, path = URL:match ('^([/%.%-%+:%a%d]+)([/%?#].*)$'); -- split the URL into scheme plus domain and path if path then -- if there is a path portion path = path:gsub ('[%[%]]', {['['] = '%5b', [']'] = '%5d'}); -- replace '[' and ']' with their percent-encoded values URL = table.concat ({domain, path}); -- and reassemble end base_url = table.concat ({ "[", URL, " ", safe_for_url (label), "]" }); -- assemble a wiki-markup URL if utilities.is_set (access) then -- access level (subscription, registration, limited) base_url = utilities.substitute (cfg.presentation['ext-link-access-signal'], {cfg.presentation[access].class, cfg.presentation[access].title, base_url}); -- add the appropriate icon end return base_url; end --[[--------------------------< F O R M A T E _ D A T E >----------------------------------------------------- Call a calendar module that turns all non-local language dates (including ISO dates) into local language dates. Used for archiving and review dates. ]] local function formatDate(txtDateIn, strFormat, params) local txtDateOut, date, status = boxDate(txtDateIn, strFormat, params) if status.brk then return error(status.errorText) else return txtDateOut end end --[[--------------------------< D E P R E C A T E D _ P A R A M E T E R >-------------------------------------- Categorize and emit an error message when the citation contains one or more deprecated parameters. The function includes the offending parameter name to the error message. Only one error message is emitted regardless of the number of deprecated parameters in the citation. added_deprecated_cat is a Boolean declared in page scope variables above ]] local function deprecated_parameter(name) if not added_deprecated_cat then added_deprecated_cat = true; -- note that we've added this category utilities.set_message ('err_deprecated_params', {name}); -- add error message end end --[=[-------------------------< K E R N _ Q U O T E S >-------------------------------------------------------- Apply kerning to open the space between the quote mark provided by the module and a leading or trailing quote mark contained in a |title= or |chapter= parameter's value. This function will positive kern either single or double quotes: "'Unkerned title with leading and trailing single quote marks'" " 'Kerned title with leading and trailing single quote marks' " (in real life the kerning isn't as wide as this example) Double single quotes (italic or bold wiki-markup) are not kerned. Replaces Unicode quote marks in plain text or in the label portion of a [[L|D]] style wikilink with typewriter quote marks regardless of the need for kerning. Unicode quote marks are not replaced in simple [[D]] wikilinks. Call this function for chapter titles, for website titles, etc.; not for book titles. ]=] local function kern_quotes (str) local cap = ''; local wl_type, label, link; wl_type, label, link = utilities.is_wikilink (str); -- wl_type is: 0, no wl (text in label variable); 1, [[D]]; 2, [[L|D]] if 1 == wl_type then -- [[D]] simple wikilink with or without quote marks if mw.ustring.match (str, '%[%[[\"“”\'‘’].+[\"“”\'‘’]%]%]') then -- leading and trailing quote marks str = utilities.substitute (cfg.presentation['kern-left'], str); str = utilities.substitute (cfg.presentation['kern-right'], str); elseif mw.ustring.match (str, '%[%[[\"“”\'‘’].+%]%]') then -- leading quote marks str = utilities.substitute (cfg.presentation['kern-left'], str); elseif mw.ustring.match (str, '%[%[.+[\"“”\'‘’]%]%]') then -- trailing quote marks str = utilities.substitute (cfg.presentation['kern-right'], str); end else -- plain text or [[L|D]]; text in label variable label = mw.ustring.gsub (label, '[“”]', '\"'); -- replace “” (U+201C & U+201D) with " (typewriter double quote mark) label = mw.ustring.gsub (label, '[‘’]', '\''); -- replace ‘’ (U+2018 & U+2019) with ' (typewriter single quote mark) cap = mw.ustring.match (label, "^([\"\'][^\'].+)"); -- match leading double or single quote but not doubled single quotes (italic markup) if utilities.is_set (cap) then label = utilities.substitute (cfg.presentation['kern-left'], cap); end cap = mw.ustring.match (label, "^(.+[^\'][\"\'])$") -- match trailing double or single quote but not doubled single quotes (italic markup) if utilities.is_set (cap) then label = utilities.substitute (cfg.presentation['kern-right'], cap); end if 2 == wl_type then str = utilities.make_wikilink (link, label); -- reassemble the wikilink else str = label; end end return str; end --[[--------------------------< F O R M A T _ S C R I P T _ V A L U E >---------------------------------------- |script-title= holds title parameters that are not written in Latin-based scripts: Chinese, Japanese, Arabic, Hebrew, etc. These scripts should not be italicized and may be written right-to-left. The value supplied by |script-title= is concatenated onto Title after Title has been wrapped in italic markup. Regardless of language, all values provided by |script-title= are wrapped in <bdi>...</bdi> tags to isolate RTL languages from the English left to right. |script-title= provides a unique feature. The value in |script-title= may be prefixed with a two-character ISO 639-1 language code and a colon: |script-title=ja:*** *** (where * represents a Japanese character) Spaces between the two-character code and the colon and the colon and the first script character are allowed: |script-title=ja : *** *** |script-title=ja: *** *** |script-title=ja :*** *** Spaces preceding the prefix are allowed: |script-title = ja:*** *** The prefix is checked for validity. If it is a valid ISO 639-1 language code, the lang attribute (lang="ja") is added to the <bdi> tag so that browsers can know the language the tag contains. This may help the browser render the script more correctly. If the prefix is invalid, the lang attribute is not added. At this time there is no error message for this condition. Supports |script-title=, |script-chapter=, |script-<periodical>= ]] local function format_script_value (script_value, script_param) local lang=''; -- initialize to empty string local name; if script_value:match('^%l%l%l?%s*:') then -- if first 3 or 4 non-space characters are script language prefix lang = script_value:match('^(%l%l%l?)%s*:%s*%S.*'); -- get the language prefix or nil if there is no script if not utilities.is_set (lang) then utilities.set_message ('err_script_parameter', {script_param, cfg.err_msg_supl['missing title part']}); -- prefix without 'title'; add error message return ''; -- script_value was just the prefix so return empty string end -- if we get this far we have prefix and script name = cfg.lang_tag_remap[lang] or mw.language.fetchLanguageName( lang, cfg.this_wiki_code ); -- get language name so that we can use it to categorize if utilities.is_set (name) then -- is prefix a proper ISO 639-1 language code? script_value = script_value:gsub ('^%l+%s*:%s*', ''); -- strip prefix from script -- is prefix one of these language codes? if utilities.in_array (lang, cfg.script_lang_codes) then utilities.add_prop_cat ('script', {name, lang}) else utilities.set_message ('err_script_parameter', {script_param, cfg.err_msg_supl['unknown language code']}); -- unknown script-language; add error message end lang = ' lang="' .. lang .. '" '; -- convert prefix into a lang attribute else utilities.set_message ('err_script_parameter', {script_param, cfg.err_msg_supl['invalid language code']}); -- invalid language code; add error message lang = ''; -- invalid so set lang to empty string end else utilities.set_message ('err_script_parameter', {script_param, cfg.err_msg_supl['missing prefix']}); -- no language code prefix; add error message end script_value = utilities.substitute (cfg.presentation['bdi'], {lang, script_value}); -- isolate in case script is RTL return script_value; end --[[--------------------------< S C R I P T _ C O N C A T E N A T E >------------------------------------------ Initially for |title= and |script-title=, this function concatenates those two parameter values after the script value has been wrapped in <bdi> tags. ]] local function script_concatenate (title, script, script_param) if utilities.is_set (script) then script = format_script_value (script, script_param); -- <bdi> tags, lang attribute, categorization, etc.; returns empty string on error if utilities.is_set (script) then title = title .. ' ' .. script; -- concatenate title and script title end end return title; end --[[--------------------------< W R A P _ M S G >-------------------------------------------------------------- Applies additional message text to various parameter values. Supplied string is wrapped using a message_list configuration taking one argument. Supports lower case text for {{citation}} templates. Additional text taken from citation_config.messages - the reason this function is similar to but separate from wrap_style(). ]] local function wrap_msg (key, str, lower) if not utilities.is_set ( str ) then return ""; end if true == lower then local msg; msg = cfg.messages[key]:lower(); -- set the message to lower case before return utilities.substitute ( msg, str ); -- including template text else return utilities.substitute ( cfg.messages[key], str ); end end --[[----------------< W I K I S O U R C E _ U R L _ M A K E >------------------- Makes a Wikisource URL from Wikisource interwiki-link. Returns the URL and appropriate label; nil else. str is the value assigned to |chapter= (or aliases) or |title= or |title-link= ]] local function wikisource_url_make (str) local wl_type, D, L; local ws_url, ws_label; local wikisource_prefix = table.concat ({'https://', cfg.this_wiki_code, '.wikisource.org/wiki/'}); wl_type, D, L = utilities.is_wikilink (str); -- wl_type is 0 (not a wikilink), 1 (simple wikilink), 2 (complex wikilink) if 0 == wl_type then -- not a wikilink; might be from |title-link= str = D:match ('^[Ww]ikisource:(.+)') or D:match ('^[Ss]:(.+)'); -- article title from interwiki link with long-form or short-form namespace if utilities.is_set (str) then ws_url = table.concat ({ -- build a Wikisource URL wikisource_prefix, -- prefix str, -- article title }); ws_label = str; -- label for the URL end elseif 1 == wl_type then -- simple wikilink: [[Wikisource:ws article]] str = D:match ('^[Ww]ikisource:(.+)') or D:match ('^[Ss]:(.+)'); -- article title from interwiki link with long-form or short-form namespace if utilities.is_set (str) then ws_url = table.concat ({ -- build a Wikisource URL wikisource_prefix, -- prefix str, -- article title }); ws_label = str; -- label for the URL end elseif 2 == wl_type then -- non-so-simple wikilink: [[Wikisource:ws article|displayed text]] ([[L|D]]) str = L:match ('^[Ww]ikisource:(.+)') or L:match ('^[Ss]:(.+)'); -- article title from interwiki link with long-form or short-form namespace if utilities.is_set (str) then ws_label = D; -- get ws article name from display portion of interwiki link ws_url = table.concat ({ -- build a Wikisource URL wikisource_prefix, -- prefix str, -- article title without namespace from link portion of wikilink }); end end if ws_url then ws_url = mw.uri.encode (ws_url, 'WIKI'); -- make a usable URL ws_url = ws_url:gsub ('%%23', '#'); -- undo percent-encoding of fragment marker end return ws_url, ws_label, L or D; -- return proper URL or nil and a label or nil end --[[----------------< F O R M A T _ P E R I O D I C A L >----------------------- Format the three periodical parameters: |script-<periodical>=, |<periodical>=, and |trans-<periodical>= into a single Periodical meta-parameter. ]] local function format_periodical (script_periodical, script_periodical_source, periodical, trans_periodical) if not utilities.is_set (periodical) then periodical = ''; -- to be safe for concatenation else periodical = utilities.wrap_style ('italic-title', periodical); -- style end periodical = script_concatenate (periodical, script_periodical, script_periodical_source); -- <bdi> tags, lang attribute, categorization, etc.; must be done after title is wrapped if utilities.is_set (trans_periodical) then trans_periodical = utilities.wrap_style ('trans-italic-title', trans_periodical); if utilities.is_set (periodical) then periodical = periodical .. ' ' .. trans_periodical; else -- here when trans-periodical without periodical or script-periodical periodical = trans_periodical; utilities.set_message ('err_trans_missing_title', {'periodical'}); end end return periodical; end --[[------------------< F O R M A T _ C H A P T E R _ T I T L E >--------------- Format the four chapter parameters: |script-chapter=, |chapter=, |trans-chapter=, and |chapter-url= into a single chapter meta- parameter (chapter_url_source used for error messages). ]] local function format_chapter_title (script_chapter, script_chapter_source, chapter, chapter_source, trans_chapter, trans_chapter_source, chapter_url, chapter_url_source, no_quotes, access) local ws_url, ws_label, L = wikisource_url_make (chapter); -- make a wikisource URL and label from a wikisource interwiki link if ws_url then ws_label = ws_label:gsub ('_', ' '); -- replace underscore separators with space characters chapter = ws_label; end if not utilities.is_set (chapter) then chapter = ''; -- to be safe for concatenation else if false == no_quotes then chapter = kern_quotes (chapter); -- if necessary, separate chapter title's leading and trailing quote marks from module provided quote marks chapter = utilities.wrap_style ('quoted-title', chapter); end end chapter = script_concatenate (chapter, script_chapter, script_chapter_source); -- <bdi> tags, lang attribute, categorization, etc.; must be done after title is wrapped if utilities.is_set (chapter_url) then chapter = external_link (chapter_url, chapter, chapter_url_source, access); -- adds bare_url_missing_title error if appropriate elseif ws_url then chapter = external_link (ws_url, chapter .. '&nbsp;', 'ws link in chapter'); -- adds bare_url_missing_title error if appropriate; space char to move icon away from chap text; TODO: better way to do this? chapter = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], L, chapter}); end if utilities.is_set (trans_chapter) then trans_chapter = utilities.wrap_style ('trans-quoted-title', trans_chapter); if utilities.is_set (chapter) then chapter = chapter .. ' ' .. trans_chapter; else -- here when trans_chapter without chapter or script-chapter chapter = trans_chapter; chapter_source = trans_chapter_source:match ('trans%-?(.+)'); -- when no chapter, get matching name from trans-<param> utilities.set_message ('err_trans_missing_title', {chapter_source}); end end return chapter; end --[[----------------< H A S _ I N V I S I B L E _ C H A R S >------------------- This function searches a parameter's value for non-printable or invisible characters. The search stops at the first match. This function will detect the visible replacement character when it is part of the Wikisource. Detects but ignores nowiki and math stripmarkers. Also detects other named stripmarkers (gallery, math, pre, ref) and identifies them with a slightly different error message. See also coins_cleanup(). Output of this function is an error message that identifies the character or the Unicode group, or the stripmarker that was detected along with its position (or, for multi-byte characters, the position of its first byte) in the parameter value. ]] local function has_invisible_chars (param, v) local position = ''; -- position of invisible char or starting position of stripmarker local capture; -- used by stripmarker detection to hold name of the stripmarker local stripmarker; -- boolean set true when a stripmarker is found capture = string.match (v, '[%w%p ]*'); -- test for values that are simple ASCII text and bypass other tests if true if capture == v then -- if same there are no Unicode characters return; end for _, invisible_char in ipairs (cfg.invisible_chars) do local char_name = invisible_char[1]; -- the character or group name local pattern = invisible_char[2]; -- the pattern used to find it position, _, capture = mw.ustring.find (v, pattern); -- see if the parameter value contains characters that match the pattern if position and (cfg.invisible_defs.zwj == capture) then -- if we found a zero-width joiner character if mw.ustring.find (v, cfg.indic_script) then -- it's ok if one of the Indic scripts position = nil; -- unset position elseif cfg.emoji_t[mw.ustring.codepoint (v, position+1)] then -- is zwj followed by a character listed in emoji{}? position = nil; -- unset position end end if position then if 'nowiki' == capture or 'math' == capture or -- nowiki and math stripmarkers (not an error condition) ('templatestyles' == capture and utilities.in_array (param, {'id', 'quote'})) then -- templatestyles stripmarker allowed in these parameters stripmarker = true; -- set a flag elseif true == stripmarker and cfg.invisible_defs.del == capture then -- because stripmakers begin and end with the delete char, assume that we've found one end of a stripmarker position = nil; -- unset else local err_msg; if capture and not (cfg.invisible_defs.del == capture or cfg.invisible_defs.zwj == capture) then err_msg = capture .. ' ' .. char_name; else err_msg = char_name .. ' ' .. 'character'; end utilities.set_message ('err_invisible_char', {err_msg, utilities.wrap_style ('parameter', param), position}); -- add error message return; -- and done with this parameter end end end end --[[-------------------< A R G U M E N T _ W R A P P E R >---------------------- Argument wrapper. This function provides support for argument mapping defined in the configuration file so that multiple names can be transparently aliased to single internal variable. ]] local function argument_wrapper ( args ) local origin = {}; return setmetatable({ ORIGIN = function ( self, k ) local dummy = self[k]; -- force the variable to be loaded. return origin[k]; end }, { __index = function ( tbl, k ) if origin[k] ~= nil then return nil; end local args, list, v = args, cfg.aliases[k]; if type( list ) == 'table' then v, origin[k] = utilities.select_one ( args, list, 'err_redundant_parameters' ); if origin[k] == nil then origin[k] = ''; -- Empty string, not nil end elseif list ~= nil then v, origin[k] = args[list], list; else -- maybe let through instead of raising an error? -- v, origin[k] = args[k], k; error( cfg.messages['unknown_argument_map'] .. ': ' .. k); end -- Empty strings, not nil; if v == nil then v = ''; origin[k] = ''; end tbl = rawset( tbl, k, v ); return v; end, }); end --[[--------------------------< N O W R A P _ D A T E >------------------------- When date is YYYY-MM-DD format wrap in nowrap span: <span ...>YYYY-MM-DD</span>. When date is DD MMMM YYYY or is MMMM DD, YYYY then wrap in nowrap span: <span ...>DD MMMM</span> YYYY or <span ...>MMMM DD,</span> YYYY DOES NOT yet support MMMM YYYY or any of the date ranges. ]] local function nowrap_date (date) local cap = ''; local cap2 = ''; if date:match("^%d%d%d%d%-%d%d%-%d%d$") then date = utilities.substitute (cfg.presentation['nowrap1'], date); elseif date:match("^%a+%s*%d%d?,%s+%d%d%d%d$") or date:match ("^%d%d?%s*%a+%s+%d%d%d%d$") then cap, cap2 = string.match (date, "^(.*)%s+(%d%d%d%d)$"); date = utilities.substitute (cfg.presentation['nowrap2'], {cap, cap2}); end return date; end --[[--------------------------< S E T _ T I T L E T Y P E >--------------------- This function sets default title types (equivalent to the citation including |type=<default value>) for those templates that have defaults. Also handles the special case where it is desirable to omit the title type from the rendered citation (|type=none). ]] local function set_titletype (cite_class, title_type) if utilities.is_set (title_type) then if 'none' == cfg.keywords_xlate[title_type] then title_type = ''; -- if |type=none then type parameter not displayed end return title_type; -- if |type= has been set to any other value use that value end return cfg.title_types [cite_class] or ''; -- set template's default title type; else empty string for concatenation end --[[--------------------------< S A F E _ J O I N >----------------------------- Joins a sequence of strings together while checking for duplicate separation characters. ]] local function safe_join( tbl, duplicate_char ) local f = {}; -- create a function table appropriate to type of 'duplicate character' if 1 == #duplicate_char then -- for single byte ASCII characters use the string library functions f.gsub = string.gsub f.match = string.match f.sub = string.sub else -- for multi-byte characters use the ustring library functions f.gsub = mw.ustring.gsub f.match = mw.ustring.match f.sub = mw.ustring.sub end local str = ''; -- the output string local comp = ''; -- what does 'comp' mean? local end_chr = ''; local trim; for _, value in ipairs( tbl ) do if value == nil then value = ''; end if str == '' then -- if output string is empty str = value; -- assign value to it (first time through the loop) elseif value ~= '' then if value:sub(1, 1) == '<' then -- special case of values enclosed in spans and other markup. comp = value:gsub( "%b<>", "" ); -- remove HTML markup (<span>string</span> -> string) else comp = value; end -- typically duplicate_char is sepc if f.sub(comp, 1, 1) == duplicate_char then -- is first character same as duplicate_char? why test first character? -- Because individual string segments often (always?) begin with terminal punct for the -- preceding segment: 'First element' .. 'sepc next element' .. etc.? trim = false; end_chr = f.sub(str, -1, -1); -- get the last character of the output string -- str = str .. "<HERE(enchr=" .. end_chr .. ")" -- debug stuff? if end_chr == duplicate_char then -- if same as separator str = f.sub(str, 1, -2); -- remove it elseif end_chr == "'" then -- if it might be wiki-markup if f.sub(str, -3, -1) == duplicate_char .. "''" then -- if last three chars of str are sepc'' str = f.sub(str, 1, -4) .. "''"; -- remove them and add back '' elseif f.sub(str, -5, -1) == duplicate_char .. "]]''" then -- if last five chars of str are sepc]]'' trim = true; -- why? why do this and next differently from previous? elseif f.sub(str, -4, -1) == duplicate_char .. "]''" then -- if last four chars of str are sepc]'' trim = true; -- same question end elseif end_chr == "]" then -- if it might be wiki-markup if f.sub(str, -3, -1) == duplicate_char .. "]]" then -- if last three chars of str are sepc]] wikilink trim = true; elseif f.sub(str, -3, -1) == duplicate_char .. '"]' then -- if last three chars of str are sepc"] quoted external link trim = true; elseif f.sub(str, -2, -1) == duplicate_char .. "]" then -- if last two chars of str are sepc] external link trim = true; elseif f.sub(str, -4, -1) == duplicate_char .. "'']" then -- normal case when |url=something & |title=Title. trim = true; end elseif end_chr == " " then -- if last char of output string is a space if f.sub(str, -2, -1) == duplicate_char .. " " then -- if last two chars of str are <sepc><space> str = f.sub(str, 1, -3); -- remove them both end end if trim then if value ~= comp then -- value does not equal comp when value contains HTML markup local dup2 = duplicate_char; if f.match(dup2, "%A" ) then dup2 = "%" .. dup2; end -- if duplicate_char not a letter then escape it value = f.gsub(value, "(%b<>)" .. dup2, "%1", 1 ) -- remove duplicate_char if it follows HTML markup else value = f.sub(value, 2, -1 ); -- remove duplicate_char when it is first character end end end str = str .. value; -- add it to the output string end end return str; end --[[--------------------------< I S _ S U F F I X >----------------------------- returns true if suffix is properly formed Jr, Sr, or ordinal in the range 1–9. Puncutation not allowed. ]] local function is_suffix (suffix) if utilities.in_array (suffix, {'Jr', 'Sr', 'Jnr', 'Snr', '1st', '2nd', '3rd'}) or suffix:match ('^%dth$') then return true; end return false; end --[[--------------------< I S _ G O O D _ V A N C _ N A M E >------------------- For Vancouver style, author/editor names are supposed to be rendered in Latin (read ASCII) characters. When a name uses characters that contain diacritical marks, those characters are to be converted to the corresponding Latin character. When a name is written using a non-Latin alphabet or logogram, that name is to be transliterated into Latin characters. The module doesn't do this so editors may/must. This test allows |first= and |last= names to contain any of the letters defined in the four Unicode Latin character sets [http://www.unicode.org/charts/PDF/U0000.pdf C0 Controls and Basic Latin] 0041–005A, 0061–007A [http://www.unicode.org/charts/PDF/U0080.pdf C1 Controls and Latin-1 Supplement] 00C0–00D6, 00D8–00F6, 00F8–00FF [http://www.unicode.org/charts/PDF/U0100.pdf Latin Extended-A] 0100–017F [http://www.unicode.org/charts/PDF/U0180.pdf Latin Extended-B] 0180–01BF, 01C4–024F |lastn= also allowed to contain hyphens, spaces, and apostrophes. (http://www.ncbi.nlm.nih.gov/books/NBK7271/box/A35029/) |firstn= also allowed to contain hyphens, spaces, apostrophes, and periods This original test: if nil == mw.ustring.find (last, "^[A-Za-zÀ-ÖØ-öø-ƿDŽ-ɏ%-%s%']*$") or nil == mw.ustring.find (first, "^[A-Za-zÀ-ÖØ-öø-ƿDŽ-ɏ%-%s%'%.]+[2-6%a]*$") then was written outside of the code editor and pasted here because the code editor gets confused between character insertion point and cursor position. The test has been rewritten to use decimal character escape sequence for the individual bytes of the Unicode characters so that it is not necessary to use an external editor to maintain this code. \195\128-\195\150 – À-Ö (U+00C0–U+00D6 – C0 controls) \195\152-\195\182 – Ø-ö (U+00D8-U+00F6 – C0 controls) \195\184-\198\191 – ø-ƿ (U+00F8-U+01BF – C0 controls, Latin extended A & B) \199\132-\201\143 – DŽ-ɏ (U+01C4-U+024F – Latin extended B) ]] local function is_good_vanc_name (last, first, suffix, position) if not suffix then if first:find ('[,%s]') then -- when there is a space or comma, might be first name/initials + generational suffix first = first:match ('(.-)[,%s]+'); -- get name/initials suffix = first:match ('[,%s]+(.+)$'); -- get generational suffix end end if utilities.is_set (suffix) then if not is_suffix (suffix) then add_vanc_error (cfg.err_msg_supl.suffix, position); return false; -- not a name with an appropriate suffix end end if nil == mw.ustring.find (last, "^[A-Za-z\195\128-\195\150\195\152-\195\182\195\184-\198\191\199\132-\201\143\225\184\128-\225\187\191%-%s%']*$") or nil == mw.ustring.find (first, "^[A-Za-z\195\128-\195\150\195\152-\195\182\195\184-\198\191\199\132-\201\143\225\184\128-\225\187\191%-%s%'%.]*$") then add_vanc_error (cfg.err_msg_supl['non-Latin char'], position); return false; -- not a string of Latin characters; Vancouver requires Romanization end; return true; end --[[--------------------------< R E D U C E _ T O _ I N I T I A L S >------------------------------------------ Attempts to convert names to initials in support of |name-list-style=vanc. Names in |firstn= may be separated by spaces or hyphens, or for initials, a period. See http://www.ncbi.nlm.nih.gov/books/NBK7271/box/A35062/. Vancouver style requires family rank designations (Jr, II, III, etc.) to be rendered as Jr, 2nd, 3rd, etc. See http://www.ncbi.nlm.nih.gov/books/NBK7271/box/A35085/. This code only accepts and understands generational suffix in the Vancouver format because Roman numerals look like, and can be mistaken for, initials. This function uses ustring functions because firstname initials may be any of the Unicode Latin characters accepted by is_good_vanc_name (). ]] local function reduce_to_initials (first, position) if first:find (',', 1, true) then return first; -- commas not allowed; abandon end local name, suffix = mw.ustring.match (first, "^(%u+) ([%dJS][%drndth]+)$"); if not name then -- if not initials and a suffix name = mw.ustring.match (first, "^(%u+)$"); -- is it just initials? end if name then -- if first is initials with or without suffix if 3 > mw.ustring.len (name) then -- if one or two initials if suffix then -- if there is a suffix if is_suffix (suffix) then -- is it legitimate? return first; -- one or two initials and a valid suffix so nothing to do else add_vanc_error (cfg.err_msg_supl.suffix, position); -- one or two initials with invalid suffix so error message return first; -- and return first unmolested end else return first; -- one or two initials without suffix; nothing to do end end end -- if here then name has 3 or more uppercase letters so treat them as a word local initials_t, names_t = {}, {}; -- tables to hold name parts and initials local i = 1; -- counter for number of initials names_t = mw.text.split (first, '[%s%-]+'); -- split into a sequence of names and possible suffix while names_t[i] do -- loop through the sequence if 1 < i and names_t[i]:match ('[%dJS][%drndth]+%.?$') then -- if not the first name, and looks like a suffix (may have trailing dot) names_t[i] = names_t[i]:gsub ('%.', ''); -- remove terminal dot if present if is_suffix (names_t[i]) then -- if a legitimate suffix table.insert (initials_t, ' ' .. names_t[i]); -- add a separator space, insert at end of initials sequence break; -- and done because suffix must fall at the end of a name end -- no error message if not a suffix; possibly because of Romanization end if 3 > i then table.insert (initials_t, mw.ustring.sub (names_t[i], 1, 1)); -- insert the initial at end of initials sequence end i = i + 1; -- bump the counter end return table.concat (initials_t); -- Vancouver format does not include spaces. end --[[--------------------------< I N T E R W I K I _ P R E F I X E N _ G E T >---------------------------------- extract interwiki prefixen from <value>. Returns two one or two values: false – no prefixen nil – prefix exists but not recognized project prefix, language prefix – when value has either of: :<project>:<language>:<article> :<language>:<project>:<article> project prefix, nil – when <value> has only a known single-letter prefix nil, language prefix – when <value> has only a known language prefix accepts single-letter project prefixen: 'd' (wikidata), 's' (wikisource), and 'w' (wikipedia) prefixes; at this writing, the other single-letter prefixen (b (wikibook), c (commons), m (meta), n (wikinews), q (wikiquote), and v (wikiversity)) are not supported. ]] local function interwiki_prefixen_get (value, is_link) if not value:find (':%l+:') then -- if no prefix return false; -- abandon; boolean here to distinguish from nil fail returns later end local prefix_patterns_linked_t = { -- sequence of valid interwiki and inter project prefixen '^%[%[:([dsw]):(%l%l+):', -- wikilinked; project and language prefixes '^%[%[:(%l%l+):([dsw]):', -- wikilinked; language and project prefixes '^%[%[:([dsw]):', -- wikilinked; project prefix '^%[%[:(%l%l+):', -- wikilinked; language prefix } local prefix_patterns_unlinked_t = { -- sequence of valid interwiki and inter project prefixen '^:([dsw]):(%l%l+):', -- project and language prefixes '^:(%l%l+):([dsw]):', -- language and project prefixes '^:([dsw]):', -- project prefix '^:(%l%l+):', -- language prefix } local cap1, cap2; for _, pattern in ipairs ((is_link and prefix_patterns_linked_t) or prefix_patterns_unlinked_t) do cap1, cap2 = value:match (pattern); if cap1 then break; -- found a match so stop looking end end if cap1 and cap2 then -- when both then :project:language: or :language:project: (both forms allowed) if 1 == #cap1 then -- length == 1 then :project:language: if cfg.inter_wiki_map[cap2] then -- is language prefix in the interwiki map? return cap1, cap2; -- return interwiki project and interwiki language end else -- here when :language:project: if cfg.inter_wiki_map[cap1] then -- is language prefix in the interwiki map? return cap2, cap1; -- return interwiki project and interwiki language end end return nil; -- unknown interwiki language elseif not (cap1 or cap2) then -- both are nil? return nil; -- we got something that looks like a project prefix but isn't; return fail elseif 1 == #cap1 then -- here when one capture return cap1, nil; -- length is 1 so return project, nil language else -- here when one capture and its length it more than 1 if cfg.inter_wiki_map[cap1] then -- is language prefix in the interwiki map? return nil, cap1; -- return nil project, language end end end --[[--------------------------< L I S T _ P E O P L E >-------------------------- Formats a list of people (authors, contributors, editors, interviewers, translators) names in the list will be linked when |<name>-link= has a value |<name>-mask- does NOT have a value; masked names are presumed to have been rendered previously so should have been linked there when |<name>-mask=0, the associated name is not rendered ]] local function list_people (control, people, etal) local sep; local namesep; local format = control.format; local maximum = control.maximum; local name_list = {}; if 'vanc' == format then -- Vancouver-like name styling? sep = cfg.presentation['sep_nl_vanc']; -- name-list separator between names is a comma namesep = cfg.presentation['sep_name_vanc']; -- last/first separator is a space else sep = cfg.presentation['sep_nl']; -- name-list separator between names is a semicolon namesep = cfg.presentation['sep_name']; -- last/first separator is <comma><space> end if sep:sub (-1, -1) ~= " " then sep = sep .. " " end if utilities.is_set (maximum) and maximum < 1 then return "", 0; end -- returned 0 is for EditorCount; not used for other names for i, person in ipairs (people) do if utilities.is_set (person.last) then local mask = person.mask; local one; local sep_one = sep; if utilities.is_set (maximum) and i > maximum then etal = true; break; end if mask then local n = tonumber (mask); -- convert to a number if it can be converted; nil else if n then one = 0 ~= n and string.rep("&mdash;", n) or nil; -- make a string of (n > 0) mdashes, nil else, to replace name person.link = nil; -- don't create link to name if name is replaces with mdash string or has been set nil else one = mask; -- replace name with mask text (must include name-list separator) sep_one = " "; -- modify name-list separator end else one = person.last; -- get surname local first = person.first -- get given name if utilities.is_set (first) then if ("vanc" == format) then -- if Vancouver format one = one:gsub ('%.', ''); -- remove periods from surnames (http://www.ncbi.nlm.nih.gov/books/NBK7271/box/A35029/) if not person.corporate and is_good_vanc_name (one, first, nil, i) then -- and name is all Latin characters; corporate authors not tested first = reduce_to_initials (first, i); -- attempt to convert first name(s) to initials end end one = one .. namesep .. first; end end if utilities.is_set (person.link) then one = utilities.make_wikilink (person.link, one); -- link author/editor end if one then -- if <one> has a value (name, mdash replacement, or mask text replacement) local proj, tag = interwiki_prefixen_get (one, true); -- get the interwiki prefixen if present if 'w' == proj and ('Wikipedia' == mw.site.namespaces.Project['name']) then proj = nil; -- for stuff like :w:de:<article>, :w is unnecessary TODO: maint cat? end if proj then proj = ({['d'] = 'Wikidata', ['s'] = 'Wikisource', ['w'] = 'Wikipedia'})[proj]; -- :w (wikipedia) for linking from a non-wikipedia project if proj then one = one .. utilities.wrap_style ('interproj', proj); -- add resized leading space, brackets, static text, language name tag = nil; -- unset; don't do both project and language end end if tag == cfg.this_wiki_code then tag = nil; -- stuff like :en:<article> at en.wiki is pointless TODO: maint cat? end if tag then local lang = cfg.lang_tag_remap[tag] or cfg.mw_languages_by_tag_t[tag]; if lang then -- error messaging done in extract_names() where we know parameter names one = one .. utilities.wrap_style ('interwiki', lang); -- add resized leading space, brackets, static text, language name end end table.insert (name_list, one); -- add it to the list of names table.insert (name_list, sep_one); -- add the proper name-list separator end end end local count = #name_list / 2; -- (number of names + number of separators) divided by 2 if 0 < count then if 1 < count and not etal then if 'amp' == format then name_list[#name_list-2] = " & "; -- replace last separator with ampersand text elseif 'and' == format then if 2 == count then name_list[#name_list-2] = cfg.presentation.sep_nl_and; -- replace last separator with 'and' text else name_list[#name_list-2] = cfg.presentation.sep_nl_end; -- replace last separator with '(sep) and' text end end end name_list[#name_list] = nil; -- erase the last separator end local result = table.concat (name_list); -- construct list if etal and utilities.is_set (result) then -- etal may be set by |display-authors=etal but we might not have a last-first list result = result .. sep .. cfg.messages['et al']; -- we've got a last-first list and etal so add et al. end return result, count; -- return name-list string and count of number of names (count used for editor names only) end --[[--------------------< M A K E _ C I T E R E F _ I D >----------------------- Generates a CITEREF anchor ID if we have at least one name or a date. Otherwise returns an empty string. namelist is one of the contributor-, author-, or editor-name lists chosen in that order. year is Year or anchor_year. ]] local function make_citeref_id (namelist, year) local names={}; -- a table for the one to four names and year for i,v in ipairs (namelist) do -- loop through the list and take up to the first four last names names[i] = v.last if i == 4 then break end -- if four then done end table.insert (names, year); -- add the year at the end local id = table.concat(names); -- concatenate names and year for CITEREF id if utilities.is_set (id) then -- if concatenation is not an empty string return "CITEREF" .. id; -- add the CITEREF portion else return ''; -- return an empty string; no reason to include CITEREF id in this citation end end --[[--------------------------< C I T E _ C L A S S _A T T R I B U T E _M A K E >------------------------------ construct <cite> tag class attribute for this citation. <cite_class> – config.CitationClass from calling template <mode> – value from |mode= parameter ]] local function cite_class_attribute_make (cite_class, mode) local class_t = {}; table.insert (class_t, 'citation'); -- required for blue highlight if 'citation' ~= cite_class then table.insert (class_t, cite_class); -- identify this template for user css table.insert (class_t, utilities.is_set (mode) and mode or 'cs1'); -- identify the citation style for user css or javascript else table.insert (class_t, utilities.is_set (mode) and mode or 'cs2'); -- identify the citation style for user css or javascript end for _, prop_key in ipairs (z.prop_keys_t) do table.insert (class_t, prop_key); -- identify various properties for user css or javascript end return table.concat (class_t, ' '); -- make a big string and done end --[[---------------------< N A M E _ H A S _ E T A L >-------------------------- Evaluates the content of name parameters (author, editor, etc.) for variations on the theme of et al. If found, the et al. is removed, a flag is set to true and the function returns the modified name and the flag. This function never sets the flag to false but returns its previous state because it may have been set by previous passes through this function or by the associated |display-<names>=etal parameter ]] local function name_has_etal (name, etal, nocat, param) if utilities.is_set (name) then -- name can be nil in which case just return local patterns = cfg.et_al_patterns; -- get patterns from configuration for _, pattern in ipairs (patterns) do -- loop through all of the patterns if name:match (pattern) then -- if this 'et al' pattern is found in name name = name:gsub (pattern, ''); -- remove the offending text etal = true; -- set flag (may have been set previously here or by |display-<names>=etal) if not nocat then -- no categorization for |vauthors= utilities.set_message ('err_etal', {param}); -- and set an error if not added end end end end return name, etal; end --[[---------------------< N A M E _ I S _ N U M E R I C >---------------------- Add an error message and category when <name> parameter value does not contain letters. Add a maintenance category when <name> parameter value has numeric characters mixed with characters that are not numeric characters; could be letters and/or punctuation characters. This function will only emit one error and one maint message for the current template. Does not emit both error and maint messages/categories for the same parameter value. ]] local function name_is_numeric (name, name_alias, list_name) local patterns = { '^%D+%d', -- <name> must have digits preceded by other characters '^%D*%d+%D+', -- <name> must have digits followed by other characters } if not added_numeric_name_errs and mw.ustring.match (name, '^[%A]+$') then -- if we have not already set an error message and <name> does not have any alpha characters utilities.set_message ('err_numeric_names', name_alias); -- add an error message added_numeric_name_errs = true; -- set the flag so we emit only one error message return; -- when here no point in further testing; abandon end if not added_numeric_name_maint then -- if we have already set a maint message for _, pattern in ipairs (patterns) do -- spin through list of patterns if mw.ustring.match (name, pattern) then -- digits preceded or followed by anything but digits; %D+ includes punctuation utilities.set_message ('maint_numeric_names', cfg.special_case_translation [list_name]); -- add a maint cat for this template added_numeric_name_maint = true; -- set the flag so we emit only one maint message return; -- when here no point in further testing; abandon end end end end --[[-----------------< N A M E _ H A S _ M U L T _ N A M E S >------------------ Evaluates the content of last/surname (authors etc.) parameters for multiple names. Multiple names are indicated if there is more than one comma or any "unescaped" semicolons. Escaped semicolons are ones used as part of selected HTML entities. If the condition is met, the function adds the multiple name maintenance category. Same test for first except that commas should not appear in given names (MOS:JR says that the generational suffix does not take a separator character). Titles, degrees, postnominals, affiliations, all normally comma separated don't belong in a citation. <name> – name parameter value <list_name> – AuthorList, EditorList, etc <limit> – number of allowed commas; 1 (default) for surnames; 0 for given names returns nothing ]] local function name_has_mult_names (name, list_name, limit) local _, commas, semicolons, nbsps; limit = limit and limit or 1; if utilities.is_set (name) then _, commas = name:gsub (',', ''); -- count the number of commas _, semicolons = name:gsub (';', ''); -- count the number of semicolons -- nbsps probably should be its own separate count rather than merged in -- some way with semicolons because Lua patterns do not support the -- grouping operator that regex does, which means there is no way to add -- more entities to escape except by adding more counts with the new -- entities _, nbsps = name:gsub ('&nbsp;',''); -- count nbsps -- There is exactly 1 semicolon per &nbsp; entity, so subtract nbsps -- from semicolons to 'escape' them. If additional entities are added, -- they also can be subtracted. if limit < commas or 0 < (semicolons - nbsps) then utilities.set_message ('maint_mult_names', cfg.special_case_translation [list_name]); -- add a maint message end end end --[=[-------------------------< I S _ G E N E R I C >---------------------------------------------------------- Compares values assigned to various parameters according to the string provided as <item> in the function call. <item> can have on of two values: 'generic_names' – for name-holding parameters: |last=, |first=, |editor-last=, etc 'generic_titles' – for |title= There are two types of generic tests. The 'accept' tests look for a pattern that should not be rejected by the 'reject' test. For example, |author=[[John Smith (author)|Smith, John]] would be rejected by the 'author' reject test. But piped wikilinks with 'author' disambiguation should not be rejected so the 'accept' test prevents that from happening. Accept tests are always performed before reject tests. Each of the 'accept' and 'reject' sequence tables hold tables for en.wiki (['en']) and local.wiki (['local']) that each can hold a test sequence table The sequence table holds, at index [1], a test pattern, and, at index [2], a boolean control value. The control value tells string.find() or mw.ustring.find() to do plain-text search (true) or a pattern search (false). The intent of all this complexity is to make these searches as fast as possible so that we don't run out of processing time on very large articles. Returns true when a reject test finds the pattern or string false when an accept test finds the pattern or string nil else ]=] local function is_generic (item, value, wiki) local test_val; local str_lower = { -- use string.lower() for en.wiki (['en']) and use mw.ustring.lower() or local.wiki (['local']) ['en'] = string.lower, ['local'] = mw.ustring.lower, } local str_find = { -- use string.find() for en.wiki (['en']) and use mw.ustring.find() or local.wiki (['local']) ['en'] = string.find, ['local'] = mw.ustring.find, } local function test (val, test_t, wiki) -- local function to do the testing; <wiki> selects lower() and find() functions val = test_t[2] and str_lower[wiki](value) or val; -- when <test_t[2]> set to 'true', plaintext search using lowercase value return str_find[wiki] (val, test_t[1], 1, test_t[2]); -- return nil when not found or matched end local test_types_t = {'accept', 'reject'}; -- test accept patterns first, then reject patterns local wikis_t = {'en', 'local'}; -- do tests for each of these keys; en.wiki first, local.wiki second for _, test_type in ipairs (test_types_t) do -- for each test type for _, generic_value in pairs (cfg.special_case_translation[item][test_type]) do -- spin through the list of generic value fragments to accept or reject for _, wiki in ipairs (wikis_t) do if generic_value[wiki] then if test (value, generic_value[wiki], wiki) then -- go do the test return ('reject' == test_type); -- param value rejected, return true; false else end end end end end end --[[--------------------------< N A M E _ I S _ G E N E R I C >------------------------------------------------ calls is_generic() to determine if <name> is a 'generic name' listed in cfg.generic_names; <name_alias> is the parameter name used in error messaging ]] local function name_is_generic (name, name_alias) if not added_generic_name_errs and is_generic ('generic_names', name) then utilities.set_message ('err_generic_name', name_alias); -- set an error message added_generic_name_errs = true; end end --[[--------------------------< N A M E _ C H E C K S >-------------------------------------------------------- This function calls various name checking functions used to validate the content of the various name-holding parameters. ]] local function name_checks (last, first, list_name, last_alias, first_alias) local accept_name; if utilities.is_set (last) then last, accept_name = utilities.has_accept_as_written (last); -- remove accept-this-as-written markup when it wraps all of <last> if not accept_name then -- <last> not wrapped in accept-as-written markup name_has_mult_names (last, list_name); -- check for multiple names in the parameter name_is_numeric (last, last_alias, list_name); -- check for names that have no letters or are a mix of digits and other characters name_is_generic (last, last_alias); -- check for names found in the generic names list end end if utilities.is_set (first) then first, accept_name = utilities.has_accept_as_written (first); -- remove accept-this-as-written markup when it wraps all of <first> if not accept_name then -- <first> not wrapped in accept-as-written markup name_has_mult_names (first, list_name, 0); -- check for multiple names in the parameter; 0 is number of allowed commas in a given name name_is_numeric (first, first_alias, list_name); -- check for names that have no letters or are a mix of digits and other characters name_is_generic (first, first_alias); -- check for names found in the generic names list end local wl_type, D = utilities.is_wikilink (first); if 0 ~= wl_type then first = D; utilities.set_message ('err_bad_paramlink', first_alias); end end return last, first; -- done end --[[----------------------< E X T R A C T _ N A M E S >------------------------- Gets name list from the input arguments Searches through args in sequential order to find |lastn= and |firstn= parameters (or their aliases), and their matching link and mask parameters. Stops searching when both |lastn= and |firstn= are not found in args after two sequential attempts: found |last1=, |last2=, and |last3= but doesn't find |last4= and |last5= then the search is done. This function emits an error message when there is a |firstn= without a matching |lastn=. When there are 'holes' in the list of last names, |last1= and |last3= are present but |last2= is missing, an error message is emitted. |lastn= is not required to have a matching |firstn=. When an author or editor parameter contains some form of 'et al.', the 'et al.' is stripped from the parameter and a flag (etal) returned that will cause list_people() to add the static 'et al.' text from Module:Citation/CS1/Configuration. This keeps 'et al.' out of the template's metadata. When this occurs, an error is emitted. ]] local function extract_names(args, list_name) local names = {}; -- table of names local last; -- individual name components local first; local link; local mask; local i = 1; -- loop counter/indexer local n = 1; -- output table indexer local count = 0; -- used to count the number of times we haven't found a |last= (or alias for authors, |editor-last or alias for editors) local etal = false; -- return value set to true when we find some form of et al. in an author parameter local last_alias, first_alias, link_alias; -- selected parameter aliases used in error messaging while true do last, last_alias = utilities.select_one ( args, cfg.aliases[list_name .. '-Last'], 'err_redundant_parameters', i ); -- search through args for name components beginning at 1 first, first_alias = utilities.select_one ( args, cfg.aliases[list_name .. '-First'], 'err_redundant_parameters', i ); link, link_alias = utilities.select_one ( args, cfg.aliases[list_name .. '-Link'], 'err_redundant_parameters', i ); mask = utilities.select_one ( args, cfg.aliases[list_name .. '-Mask'], 'err_redundant_parameters', i ); if last then -- error check |lastn= alias for unknown interwiki link prefix; done here because this is where we have the parameter name local project, language = interwiki_prefixen_get (last, true); -- true because we expect interwiki links in |lastn= to be wikilinked if nil == project and nil == language then -- when both are nil utilities.set_message ('err_bad_paramlink', last_alias); -- not known, emit an error message -- TODO: err_bad_interwiki? last = utilities.remove_wiki_link (last); -- remove wikilink markup; show display value only end end if link then -- error check |linkn= alias for unknown interwiki link prefix local project, language = interwiki_prefixen_get (link, false); -- false because wiki links in |author-linkn= is an error if nil == project and nil == language then -- when both are nil utilities.set_message ('err_bad_paramlink', link_alias); -- not known, emit an error message -- TODO: err_bad_interwiki? link = nil; -- unset so we don't link link_alias = nil; end end last, etal = name_has_etal (last, etal, false, last_alias); -- find and remove variations on et al. first, etal = name_has_etal (first, etal, false, first_alias); -- find and remove variations on et al. last, first = name_checks (last, first, list_name, last_alias, first_alias); -- multiple names, extraneous annotation, etc. checks if first and not last then -- if there is a firstn without a matching lastn local alias = first_alias:find ('given', 1, true) and 'given' or 'first'; -- get first or given form of the alias utilities.set_message ('err_first_missing_last', { first_alias, -- param name of alias missing its mate first_alias:gsub (alias, {['first'] = 'last', ['given'] = 'surname'}), -- make param name appropriate to the alias form }); -- add this error message elseif not first and not last then -- if both firstn and lastn aren't found, are we done? count = count + 1; -- number of times we haven't found last and first if 2 <= count then -- two missing names and we give up break; -- normal exit or there is a two-name hole in the list; can't tell which end else -- we have last with or without a first local result; link = link_title_ok (link, link_alias, last, last_alias); -- check for improper wiki-markup if first then link = link_title_ok (link, link_alias, first, first_alias); -- check for improper wiki-markup end names[n] = {last = last, first = first, link = link, mask = mask, corporate = false}; -- add this name to our names list (corporate for |vauthors= only) n = n + 1; -- point to next location in the names table if 1 == count then -- if the previous name was missing utilities.set_message ('err_missing_name', {list_name:match ("(%w+)List"):lower(), i - 1}); -- add this error message end count = 0; -- reset the counter, we're looking for two consecutive missing names end i = i + 1; -- point to next args location end return names, etal; -- all done, return our list of names and the etal flag end --[[--------------------------< N A M E _ T A G _ G E T >------------------------------------------------------ attempt to decode |language=<lang_param> and return language name and matching tag; nil else. This function looks for: <lang_param> as a tag in cfg.lang_tag_remap{} <lang_param> as a name in cfg.lang_name_remap{} <lang_param> as a name in cfg.mw_languages_by_name_t <lang_param> as a tag in cfg.mw_languages_by_tag_t when those fail, presume that <lang_param> is an IETF-like tag that MediaWiki does not recognize. Strip all script, region, variant, whatever subtags from <lang_param> to leave just a two or three character language tag and look for the new <lang_param> in cfg.mw_languages_by_tag_t{} on success, returns name (in properly capitalized form) and matching tag (in lowercase); on failure returns nil ]] local function name_tag_get (lang_param) local lang_param_lc = mw.ustring.lower (lang_param); -- use lowercase as an index into the various tables local name; local tag; name = cfg.lang_tag_remap[lang_param_lc]; -- assume <lang_param_lc> is a tag; attempt to get remapped language name if name then -- when <name>, <lang_param> is a tag for a remapped language name if cfg.lang_name_remap[name:lower()][2] ~= lang_param_lc then utilities.set_message ('maint_unknown_lang'); -- add maint category if not already added return name, cfg.lang_name_remap[name:lower()][2]; -- so return name and tag from lang_name_remap[name]; special case to xlate sr-ec and sr-el to sr-cyrl and sr-latn end return name, lang_param_lc; -- so return <name> from remap and <lang_param_lc> end tag = lang_param_lc:match ('^(%a%a%a?)%-.*'); -- still assuming that <lang_param_lc> is a tag; strip script, region, variant subtags name = cfg.lang_tag_remap[tag]; -- attempt to get remapped language name with language subtag only if name then -- when <name>, <tag> is a tag for a remapped language name return name, tag; -- so return <name> from remap and <tag> end if cfg.lang_name_remap[lang_param_lc] then -- not a remapped tag, assume <lang_param_lc> is a name; attempt to get remapped language tag return cfg.lang_name_remap[lang_param_lc][1], cfg.lang_name_remap[lang_param_lc][2]; -- for this <lang_param_lc>, return a (possibly) new name and appropriate tag end name = cfg.mw_languages_by_tag_t[lang_param_lc]; -- assume that <lang_param_lc> is a tag; attempt to get its matching language name if name then return name, lang_param_lc; -- <lang_param_lc> is a tag so return it and <name> end tag = cfg.mw_languages_by_name_t[lang_param_lc]; -- assume that <lang_param_lc> is a language name; attempt to get its matching tag if tag then return cfg.mw_languages_by_tag_t[tag], tag; -- <lang_param_lc> is a name so return the name from the table and <tag> end tag = lang_param_lc:match ('^(%a%a%a?)%-.*'); -- is <lang_param_lc> an IETF-like tag that MediaWiki doesn't recognize? <tag> gets the language subtag; nil else if tag then name = cfg.mw_languages_by_tag_t[tag]; -- attempt to get a language name using the shortened <tag> if name then return name, tag; -- <lang_param_lc> is an unrecognized IETF-like tag so return <name> and language subtag end end end --[[-------------------< L A N G U A G E _ P A R A M E T E R >------------------ Gets language name from a provided two- or three-character ISO 639 code. If a code is recognized by MediaWiki, use the returned name; if not, then use the value that was provided with the language parameter. When |language= contains a recognized language (either code or name), the page is assigned to the category for that code: Category:Norwegian-language sources (no). For valid three-character code languages, the page is assigned to the single category for '639-2' codes: Category:CS1 ISO 639-2 language sources. Languages that are the same as the local wiki are not categorized. MediaWiki does not recognize three-character equivalents of two-character codes: code 'ar' is recognized but code 'ara' is not. This function supports multiple languages in the form |language=nb, French, th where the language names or codes are separated from each other by commas with optional space characters. ]] local function language_parameter (lang) local tag; -- some form of IETF-like language tag; language subtag with optional region, sript, vatiant, etc subtags local lang_subtag; -- ve populates |language= with mostly unecessary region subtags the MediaWiki does not recognize; this is the base language subtag local name; -- the language name local language_list = {}; -- table of language names to be rendered local names_t = {}; -- table made from the value assigned to |language= local this_wiki_name = mw.language.fetchLanguageName (cfg.this_wiki_code, cfg.this_wiki_code); -- get this wiki's language name names_t = mw.text.split (lang, '%s*,%s*'); -- names should be a comma separated list for _, lang in ipairs (names_t) do -- reuse lang here because we don't yet know if lang is a language name or a language tag local fromEnglishToCode = { -- костыль для РУВИКИ: замена распространённых англоназваний на коды, в следующей итерации использовать Module:Language. ['Arabic'] = 'ar', ['Azerbaijani'] = 'az', ['Belarusian'] = 'be', ['Bulgarian'] = 'bg', ['Czech'] = 'cs', ['Danish'] = 'da', ['German'] = 'de', ['Greek'] = 'el', ['Spanish'] = 'es', ['English'] = 'en', ['Finnish'] = 'fi', ['French'] = 'fr', ['Hebrew'] = 'he', ['Croatian'] = 'hr', ['Hungarian'] = 'hu', ['Armenian'] = 'hy', ['Indonesian'] = 'id', ['Italian'] = 'it', ['Japanese'] = 'ja', ['Korean'] = 'ko', ['Latin'] = 'la', ['Dutch'] = 'nl', ['Norwegian'] = 'no', ['Polish'] = 'pl', ['Portuguese'] = 'pt', ['Romanian'] = 'ro', ['Russian'] = 'ru', ['Slovenian'] = 'sl', ['Serbian'] = 'sr', ['Swedish'] = 'sv', ['Thai'] = 'th', ['Turkish'] = 'tr', ['Ukrainian'] = 'uk', ['Chinese'] = 'zh', } if fromEnglishToCode[lang] then lang = fromEnglishToCode[lang] end name, tag = name_tag_get (lang); -- attempt to get name/tag pair for <lang>; <name> has proper capitalization; <tag> is lowercase if utilities.is_set (tag) then lang_subtag = tag:gsub ('^(%a%a%a?)%-.*', '%1'); -- for categorization, strip any IETF-like tags from language tag if cfg.this_wiki_code ~= lang_subtag then -- when the language is not the same as this wiki's language if 2 == lang_subtag:len() then -- and is a two-character tag utilities.add_prop_cat ('foreign-lang-source', {name, tag}, lang_subtag); -- categorize it; tag appended to allow for multiple language categorization else -- or is a recognized language (but has a three-character tag) utilities.add_prop_cat ('foreign-lang-source-2', {lang_subtag}, lang_subtag); -- categorize it differently TODO: support multiple three-character tag categories per cs1|2 template? end elseif cfg.local_lang_cat_enable then -- when the language and this wiki's language are the same and categorization is enabled utilities.add_prop_cat ('local-lang-source', {name, lang_subtag}); -- categorize it end else name = lang; -- return whatever <lang> has so that we show something utilities.set_message ('maint_unknown_lang'); -- add maint category if not already added end table.insert (language_list, name); name = ''; -- so we can reuse it end name = utilities.make_sep_list (#language_list, language_list); if (1 == #language_list) and (lang_subtag == cfg.this_wiki_code) then -- when only one language, find lang name in this wiki lang name; for |language=en-us, 'English' in 'American English' return ''; -- if one language and that language is this wiki's return an empty string (no annotation) end return (mw.getCurrentFrame():expandTemplate{ -- РУВИКИ: используем шаблон для отображения языка title= utilities.substitute (cfg.messages ['language'], tag) }); -- otherwise wrap with '(in ...)' --[[ TODO: should only return blank or name rather than full list so we can clean up the bunched parenthetical elements Language, Type, Format ]] end --[[-----------------------< S E T _ C S _ S T Y L E >-------------------------- Gets the default CS style configuration for the given mode. Returns default separator and either postscript as passed in or the default. In CS1, the default postscript and separator are '.'. In CS2, the default postscript is the empty string and the default separator is ','. ]] local function set_cs_style (postscript, mode) if utilities.is_set(postscript) then -- emit a maintenance message if user postscript is the default cs1 postscript -- we catch the opposite case for cs2 in set_style if mode == 'cs1' and postscript == cfg.presentation['ps_' .. mode] then utilities.set_message ('maint_postscript'); end else postscript = cfg.presentation['ps_' .. mode]; end return cfg.presentation['sep_' .. mode], postscript; end --[[--------------------------< S E T _ S T Y L E >----------------------------- Sets the separator and postscript styles. Checks the |mode= first and the #invoke CitationClass second. Removes the postscript if postscript == none. ]] local function set_style (mode, postscript, cite_class) local sep; if 'cs2' == mode then sep, postscript = set_cs_style (postscript, 'cs2'); elseif 'cs1' == mode then sep, postscript = set_cs_style (postscript, 'cs1'); elseif 'citation' == cite_class then sep, postscript = set_cs_style (postscript, 'cs2'); else sep, postscript = set_cs_style (postscript, 'cs1'); end if cfg.keywords_xlate[postscript:lower()] == 'none' then -- emit a maintenance message if user postscript is the default cs2 postscript -- we catch the opposite case for cs1 in set_cs_style if 'cs2' == mode or ('cs1' ~= mode and 'citation' == cite_class) then -- {{citation |title=Title |mode=cs1 |postscript=none}} should not emit maint message utilities.set_message ('maint_postscript'); end postscript = ''; end return sep, postscript end --[=[-------------------------< I S _ P D F >----------------------------------- Determines if a URL has the file extension that is one of the PDF file extensions used by [[MediaWiki:Common.css]] when applying the PDF icon to external links. returns true if file extension is one of the recognized extensions, else false ]=] local function is_pdf (url) return url:match ('%.pdf$') or url:match ('%.PDF$') or url:match ('%.pdf[%?#]') or url:match ('%.PDF[%?#]') or url:match ('%.PDF&#035') or url:match ('%.pdf&#035'); end --[[--------------------------< S T Y L E _ F O R M A T >----------------------- Applies CSS style to |format=, |chapter-format=, etc. Also emits an error message if the format parameter does not have a matching URL parameter. If the format parameter is not set and the URL contains a file extension that is recognized as a PDF document by MediaWiki's commons.css, this code will set the format parameter to (PDF) with the appropriate styling. ]] local function style_format (format, url, fmt_param, url_param) if utilities.is_set (format) then format = utilities.wrap_style ('format', format); -- add leading space, parentheses, resize if not utilities.is_set (url) then utilities.set_message ('err_format_missing_url', {fmt_param, url_param}); -- add an error message end elseif is_pdf (url) then -- format is not set so if URL is a PDF file then format = utilities.wrap_style ('format', 'PDF'); -- set format to PDF else format = ''; -- empty string for concatenation end return format; end --[[---------------------< G E T _ D I S P L A Y _ N A M E S >------------------ Returns a number that defines the number of names displayed for author and editor name lists and a Boolean flag to indicate when et al. should be appended to the name list. When the value assigned to |display-xxxxors= is a number greater than or equal to zero, return the number and the previous state of the 'etal' flag (false by default but may have been set to true if the name list contains some variant of the text 'et al.'). When the value assigned to |display-xxxxors= is the keyword 'etal', return a number that is one greater than the number of authors in the list and set the 'etal' flag true. This will cause the list_people() to display all of the names in the name list followed by 'et al.' In all other cases, returns nil and the previous state of the 'etal' flag. inputs: max: A['DisplayAuthors'] or A['DisplayEditors'], etc; a number or some flavor of etal count: #a or #e list_name: 'authors' or 'editors' etal: author_etal or editor_etal This function sets an error message when |display-xxxxors= value greater than or equal to number of names but not when <max> comes from {{cs1 config}} global settings. When using global settings, <param> is set to the keyword 'cs1 config' which is used to supress the normal error. Error is suppressed because it is to be expected that some citations in an article will have the same or fewer names that the limit specified in {{cs1 config}}. ]] local function get_display_names (max, count, list_name, etal, param) if utilities.is_set (max) then if 'etal' == max:lower():gsub("[ '%.]", '') then -- the :gsub() portion makes 'etal' from a variety of 'et al.' spellings and stylings max = count + 1; -- number of authors + 1 so display all author name plus et al. etal = true; -- overrides value set by extract_names() elseif max:match ('^%d+$') then -- if is a string of numbers max = tonumber (max); -- make it a number if (max >= count) and ('cs1 config' ~= param) then -- error when local |display-xxxxors= value greater than or equal to number of names; not an error when using global setting utilities.set_message ('err_disp_name', {param, max}); -- add error message max = nil; end else -- not a valid keyword or number utilities.set_message ('err_disp_name', {param, max}); -- add error message max = nil; -- unset; as if |display-xxxxors= had not been set end end return max, etal; end --[[----------< E X T R A _ T E X T _ I N _ P A G E _ C H E C K >--------------- Adds error if |page=, |pages=, |quote-page=, |quote-pages= has what appears to be some form of p. or pp. abbreviation in the first characters of the parameter content. check page for extraneous p, p., pp, pp., pg, pg. at start of parameter value: good pattern: '^P[^%.P%l]' matches when page begins PX or P# but not Px where x and X are letters and # is a digit bad pattern: '^[Pp][PpGg]' matches when page begins pp, pP, Pp, PP, pg, pG, Pg, PG ]] local function extra_text_in_page_check (val, name) if not val:match (cfg.vol_iss_pg_patterns.good_ppattern) then for _, pattern in ipairs (cfg.vol_iss_pg_patterns.bad_ppatterns) do -- spin through the selected sequence table of patterns if val:match (pattern) then -- when a match, error so utilities.set_message ('err_extra_text_pages', name); -- add error message return; -- and done end end end end --[[--------------------------< E X T R A _ T E X T _ I N _ V O L _ I S S _ C H E C K >------------------------ Adds error if |volume= or |issue= has what appears to be some form of redundant 'type' indicator. Applies to both; this function looks for issue text in both |issue= and |volume= and looks for volume-like text in |voluem= and |issue=. For |volume=: 'V.', or 'Vol.' (with or without the dot) abbreviations or 'Volume' in the first characters of the parameter content (all case insensitive). 'V' and 'v' (without the dot) are presumed to be roman numerals so are allowed. For |issue=: 'No.', 'I.', 'Iss.' (with or without the dot) abbreviations, or 'Issue' in the first characters of the parameter content (all case insensitive); numero styling: 'n°' with degree sign U+00B0, and № precomposed numero sign U+2116. Single character values ('v', 'i', 'n') allowed when not followed by separator character ('.', ':', '=', or whitespace character) – param values are trimmed of whitespace by MediaWiki before delivered to the module. <val> is |volume= or |issue= parameter value <name> is |volume= or |issue= parameter name for error message <selector> is 'v' for |volume=, 'i' for |issue= sets error message on failure; returns nothing ]] local function extra_text_in_vol_iss_check (val, name, selector) if not utilities.is_set (val) then return; end local handler = 'v' == selector and 'err_extra_text_volume' or 'err_extra_text_issue'; val = val:lower(); -- force parameter value to lower case for _, pattern in ipairs (cfg.vol_iss_pg_patterns.vi_patterns_t) do -- spin through the sequence table of patterns if val:match (pattern) then -- when a match, error so utilities.set_message (handler, name); -- add error message return; -- and done end end end --[=[-------------------------< G E T _ V _ N A M E _ T A B L E >---------------------------------------------- split apart a |vauthors= or |veditors= parameter. This function allows for corporate names, wrapped in doubled parentheses to also have commas; in the old version of the code, the doubled parentheses were included in the rendered citation and in the metadata. Individual author names may be wikilinked |vauthors=Jones AB, [[E. B. White|White EB]], ((Black, Brown, and Co.)) ]=] local function get_v_name_table (vparam, output_table, output_link_table) local name_table = mw.text.split(vparam, "%s*,%s*"); -- names are separated by commas local wl_type, label, link; -- wl_type not used here; just a placeholder local i = 1; while name_table[i] do if name_table[i]:match ('^%(%(.*[^%)][^%)]$') then -- first segment of corporate with one or more commas; this segment has the opening doubled parentheses local name = name_table[i]; i = i + 1; -- bump indexer to next segment while name_table[i] do name = name .. ', ' .. name_table[i]; -- concatenate with previous segments if name_table[i]:match ('^.*%)%)$') then -- if this table member has the closing doubled parentheses break; -- and done reassembling so end i = i + 1; -- bump indexer end table.insert (output_table, name); -- and add corporate name to the output table table.insert (output_link_table, ''); -- no wikilink else wl_type, label, link = utilities.is_wikilink (name_table[i]); -- wl_type is: 0, no wl (text in label variable); 1, [[D]]; 2, [[L|D]] table.insert (output_table, label); -- add this name if 1 == wl_type then table.insert (output_link_table, label); -- simple wikilink [[D]] else table.insert (output_link_table, link); -- no wikilink or [[L|D]]; add this link if there is one, else empty string end end i = i + 1; end return output_table; end --[[--------------------------< P A R S E _ V A U T H O R S _ V E D I T O R S >-------------------------------- This function extracts author / editor names from |vauthors= or |veditors= and finds matching |xxxxor-maskn= and |xxxxor-linkn= in args. It then returns a table of assembled names just as extract_names() does. Author / editor names in |vauthors= or |veditors= must be in Vancouver system style. Corporate or institutional names may sometimes be required and because such names will often fail the is_good_vanc_name() and other format compliance tests, are wrapped in doubled parentheses ((corporate name)) to suppress the format tests. Supports generational suffixes Jr, 2nd, 3rd, 4th–6th. This function sets the Vancouver error when a required comma is missing and when there is a space between an author's initials. ]] local function parse_vauthors_veditors (args, vparam, list_name) local names = {}; -- table of names assembled from |vauthors=, |author-maskn=, |author-linkn= local v_name_table = {}; local v_link_table = {}; -- when name is wikilinked, targets go in this table local etal = false; -- return value set to true when we find some form of et al. vauthors parameter local last, first, link, mask, suffix; local corporate = false; vparam, etal = name_has_etal (vparam, etal, true); -- find and remove variations on et al. do not categorize (do it here because et al. might have a period) v_name_table = get_v_name_table (vparam, v_name_table, v_link_table); -- names are separated by commas for i, v_name in ipairs(v_name_table) do first = ''; -- set to empty string for concatenation and because it may have been set for previous author/editor local accept_name; v_name, accept_name = utilities.has_accept_as_written (v_name); -- remove accept-this-as-written markup when it wraps all of <v_name> if accept_name then last = v_name; corporate = true; -- flag used in list_people() elseif string.find(v_name, "%s") then if v_name:find('[;%.]') then -- look for commonly occurring punctuation characters; add_vanc_error (cfg.err_msg_supl.punctuation, i); end local lastfirstTable = {} lastfirstTable = mw.text.split(v_name, "%s+") first = table.remove(lastfirstTable); -- removes and returns value of last element in table which should be initials or generational suffix if not mw.ustring.match (first, '^%u+$') then -- mw.ustring here so that later we will catch non-Latin characters suffix = first; -- not initials so assume that whatever we got is a generational suffix first = table.remove(lastfirstTable); -- get what should be the initials from the table end last = table.concat(lastfirstTable, ' ') -- returns a string that is the concatenation of all other names that are not initials and generational suffix if not utilities.is_set (last) then first = ''; -- unset last = v_name; -- last empty because something wrong with first add_vanc_error (cfg.err_msg_supl.name, i); end if mw.ustring.match (last, '%a+%s+%u+%s+%a+') then add_vanc_error (cfg.err_msg_supl['missing comma'], i); -- matches last II last; the case when a comma is missing end if mw.ustring.match (v_name, ' %u %u$') then -- this test is in the wrong place TODO: move or replace with a more appropriate test add_vanc_error (cfg.err_msg_supl.initials, i); -- matches a space between two initials end else last = v_name; -- last name or single corporate name? Doesn't support multiword corporate names? do we need this? end if utilities.is_set (first) then if not mw.ustring.match (first, "^%u?%u$") then -- first shall contain one or two upper-case letters, nothing else add_vanc_error (cfg.err_msg_supl.initials, i); -- too many initials; mixed case initials (which may be ok Romanization); hyphenated initials end is_good_vanc_name (last, first, suffix, i); -- check first and last before restoring the suffix which may have a non-Latin digit if utilities.is_set (suffix) then first = first .. ' ' .. suffix; -- if there was a suffix concatenate with the initials suffix = ''; -- unset so we don't add this suffix to all subsequent names end else if not corporate then is_good_vanc_name (last, '', nil, i); end end link = utilities.select_one ( args, cfg.aliases[list_name .. '-Link'], 'err_redundant_parameters', i ) or v_link_table[i]; mask = utilities.select_one ( args, cfg.aliases[list_name .. '-Mask'], 'err_redundant_parameters', i ); names[i] = {last = last, first = first, link = link, mask = mask, corporate = corporate}; -- add this assembled name to our names list end return names, etal; -- all done, return our list of names end --[[--------------------------< S E L E C T _ A U T H O R _ E D I T O R _ S O U R C E >------------------------ Select one of |authors=, |authorn= / |lastn / firstn=, or |vauthors= as the source of the author name list or select one of |editorn= / editor-lastn= / |editor-firstn= or |veditors= as the source of the editor name list. Only one of these appropriate three will be used. The hierarchy is: |authorn= (and aliases) highest and |authors= lowest; |editorn= (and aliases) highest and |veditors= lowest (support for |editors= withdrawn) When looking for |authorn= / |editorn= parameters, test |xxxxor1= and |xxxxor2= (and all of their aliases); stops after the second test which mimicks the test used in extract_names() when looking for a hole in the author name list. There may be a better way to do this, I just haven't discovered what that way is. Emits an error message when more than one xxxxor name source is provided. In this function, vxxxxors = vauthors or veditors; xxxxors = authors as appropriate. ]] local function select_author_editor_source (vxxxxors, xxxxors, args, list_name) local lastfirst = false; if utilities.select_one ( args, cfg.aliases[list_name .. '-Last'], 'none', 1 ) or -- do this twice in case we have a |first1= without a |last1=; this ... utilities.select_one ( args, cfg.aliases[list_name .. '-First'], 'none', 1 ) or -- ... also catches the case where |first= is used with |vauthors= utilities.select_one ( args, cfg.aliases[list_name .. '-Last'], 'none', 2 ) or utilities.select_one ( args, cfg.aliases[list_name .. '-First'], 'none', 2 ) then lastfirst = true; end if (utilities.is_set (vxxxxors) and true == lastfirst) or -- these are the three error conditions (utilities.is_set (vxxxxors) and utilities.is_set (xxxxors)) or (true == lastfirst and utilities.is_set (xxxxors)) then local err_name; if 'AuthorList' == list_name then -- figure out which name should be used in error message err_name = 'author'; else err_name = 'editor'; end utilities.set_message ('err_redundant_parameters', err_name .. '-name-list parameters'); -- add error message end if true == lastfirst then return 1 end; -- return a number indicating which author name source to use if utilities.is_set (vxxxxors) then return 2 end; if utilities.is_set (xxxxors) then return 3 end; return 1; -- no authors so return 1; this allows missing author name test to run in case there is a first without last end --[[--------------------------< I S _ V A L I D _ P A R A M E T E R _ V A L U E >------------------------------ This function is used to validate a parameter's assigned value for those parameters that have only a limited number of allowable values (yes, y, true, live, dead, etc.). When the parameter value has not been assigned a value (missing or empty in the source template) the function returns the value specified by ret_val. If the parameter value is one of the list of allowed values returns the translated value; else, emits an error message and returns the value specified by ret_val. TODO: explain <invert> ]] local function is_valid_parameter_value (value, name, possible, ret_val, invert) if not utilities.is_set (value) then return ret_val; -- an empty parameter is ok end if (not invert and utilities.in_array (value, possible)) then -- normal; <value> is in <possible> table return cfg.keywords_xlate[value]; -- return translation of parameter keyword elseif invert and not utilities.in_array (value, possible) then -- invert; <value> is not in <possible> table return value; -- return <value> as it is else utilities.set_message ('err_invalid_param_val', {name, value}); -- not an allowed value so add error message return ret_val; end end --[[--------------------------< T E R M I N A T E _ N A M E _ L I S T >---------------------------------------- This function terminates a name list (author, contributor, editor) with a separator character (sepc) and a space when the last character is not a sepc character or when the last three characters are not sepc followed by two closing square brackets (close of a wikilink). When either of these is true, the name_list is terminated with a single space character. ]] local function terminate_name_list (name_list, sepc) if (string.sub (name_list, -3, -1) == sepc .. '. ') then -- if already properly terminated return name_list; -- just return the name list elseif (string.sub (name_list, -1, -1) == sepc) or (string.sub (name_list, -3, -1) == sepc .. ']]') then -- if last name in list ends with sepc char return name_list .. " "; -- don't add another else return name_list .. sepc .. ' '; -- otherwise terminate the name list end end --[[-------------------------< F O R M A T _ V O L U M E _ I S S U E >----------------------------------------- returns the concatenation of the formatted volume and issue (or journal article number) parameters as a single string; or formatted volume or formatted issue, or an empty string if neither are set. ]] local function format_volume_issue (volume, issue, article, cite_class, origin, sepc, lower) if not utilities.is_set (volume) and not utilities.is_set (issue) and not utilities.is_set (article) then return ''; end -- same condition as in format_pages_sheets() local is_journal = 'journal' == cite_class or (utilities.in_array (cite_class, {'citation', 'map', 'interview'}) and 'journal' == origin); local is_numeric_vol = volume and (volume:match ('^[MDCLXVI]+$') or volume:match ('^%d+$')); -- is only uppercase roman numerals or only digits? local is_long_vol = volume and (4 < mw.ustring.len(volume)); -- is |volume= value longer than 4 characters? if volume and (not is_numeric_vol and is_long_vol) then -- when not all digits or Roman numerals, is |volume= longer than 4 characters? utilities.add_prop_cat ('long-vol'); -- yes, add properties cat end if is_journal then -- journal-style formatting local vol = ''; if utilities.is_set (volume) then if is_numeric_vol then -- |volume= value all digits or all uppercase Roman numerals? vol = utilities.substitute (cfg.presentation['vol-bold'], {sepc, volume}); -- render in bold face elseif is_long_vol then -- not all digits or Roman numerals; longer than 4 characters? vol = utilities.substitute (cfg.messages['j-vol'], {sepc, utilities.hyphen_to_dash (volume)}); -- not bold else -- four or fewer characters vol = utilities.substitute (cfg.presentation['vol-bold'], {sepc, utilities.hyphen_to_dash (volume)}); -- bold end end vol = vol .. (utilities.is_set (issue) and utilities.substitute (cfg.messages['j-issue'], issue) or '') vol = vol .. (utilities.is_set (article) and utilities.substitute (cfg.messages['j-article-num'], article) or '') return vol; end if 'podcast' == cite_class and utilities.is_set (issue) then return wrap_msg ('issue', {sepc, issue}, lower); end if 'conference' == cite_class and utilities.is_set (article) then -- |article-number= supported only in journal and conference cites if utilities.is_set (volume) and utilities.is_set (article) then -- both volume and article number return wrap_msg ('vol-art', {sepc, utilities.hyphen_to_dash (volume), article}, lower); elseif utilities.is_set (article) then -- article number alone; when volume alone, handled below return wrap_msg ('art', {sepc, article}, lower); end end -- all other types of citation if utilities.is_set (volume) and utilities.is_set (issue) then return wrap_msg ('vol-no', {sepc, utilities.hyphen_to_dash (volume), issue}, lower); elseif utilities.is_set (volume) then return wrap_msg ('vol', {sepc, utilities.hyphen_to_dash (volume)}, lower); else return wrap_msg ('issue', {sepc, issue}, lower); end end --[[-------------------------< F O R M A T _ P A G E S _ S H E E T S >----------------------------------------- adds static text to one of |page(s)= or |sheet(s)= values and returns it with all of the others set to empty strings. The return order is: page, pages, sheet, sheets Singular has priority over plural when both are provided. ]] local function format_pages_sheets (page, pages, sheet, sheets, cite_class, origin, sepc, nopp, lower) if 'map' == cite_class then -- only cite map supports sheet(s) as in-source locators if utilities.is_set (sheet) then if 'journal' == origin then return '', '', wrap_msg ('j-sheet', sheet, lower), ''; else return '', '', wrap_msg ('sheet', {sepc, sheet}, lower), ''; end elseif utilities.is_set (sheets) then if 'journal' == origin then return '', '', '', wrap_msg ('j-sheets', sheets, lower); else return '', '', '', wrap_msg ('sheets', {sepc, sheets}, lower); end end end local is_journal = 'journal' == cite_class or (utilities.in_array (cite_class, {'citation', 'map', 'interview'}) and 'journal' == origin); if utilities.is_set (page) then if is_journal then return utilities.substitute (cfg.messages['j-page(s)'], page), '', '', ''; elseif not nopp then return utilities.substitute (cfg.messages['p-prefix'], {sepc, page}), '', '', ''; else return utilities.substitute (cfg.messages['nopp'], {sepc, page}), '', '', ''; end elseif utilities.is_set (pages) then if is_journal then return utilities.substitute (cfg.messages['j-page(s)'], pages), '', '', ''; elseif tonumber(pages) ~= nil and not nopp then -- if pages is only digits, assume a single page number return '', utilities.substitute (cfg.messages['p-prefix'], {sepc, pages}), '', ''; elseif not nopp then return '', utilities.substitute (cfg.messages['pp-prefix'], {sepc, pages}), '', ''; else return '', utilities.substitute (cfg.messages['nopp'], {sepc, pages}), '', ''; end end return '', '', '', ''; -- return empty strings end --[[--------------------------< I N S O U R C E _ L O C _ G E T >---------------------------------------------- returns one of the in-source locators: page, pages, or at. If any of these are interwiki links to Wikisource, returns the label portion of the interwiki-link as plain text for use in COinS. This COinS thing is done because here we convert an interwiki-link to an external link and add an icon span around that; get_coins_pages() doesn't know about the span. TODO: should it? TODO: add support for sheet and sheets?; streamline; TODO: make it so that this function returns only one of the three as the single in-source (the return value assigned to a new name)? ]] local function insource_loc_get (page, page_orig, pages, pages_orig, at) local ws_url, ws_label, coins_pages, L; -- for Wikisource interwiki-links; TODO: this corrupts page metadata (span remains in place after cleanup; fix there?) if utilities.is_set (page) then if utilities.is_set (pages) or utilities.is_set (at) then pages = ''; -- unset the others at = ''; end extra_text_in_page_check (page, page_orig); -- emit error message when |page= value begins with what looks like p., pp., etc. ws_url, ws_label, L = wikisource_url_make (page); -- make ws URL from |page= interwiki link; link portion L becomes tooltip label if ws_url then page = external_link (ws_url, ws_label .. '&nbsp;', 'ws link in page'); -- space char after label to move icon away from in-source text; TODO: a better way to do this? page = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], L, page}); coins_pages = ws_label; end elseif utilities.is_set (pages) then if utilities.is_set (at) then at = ''; -- unset end extra_text_in_page_check (pages, pages_orig); -- emit error message when |page= value begins with what looks like p., pp., etc. ws_url, ws_label, L = wikisource_url_make (pages); -- make ws URL from |pages= interwiki link; link portion L becomes tooltip label if ws_url then pages = external_link (ws_url, ws_label .. '&nbsp;', 'ws link in pages'); -- space char after label to move icon away from in-source text; TODO: a better way to do this? pages = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], L, pages}); coins_pages = ws_label; end elseif utilities.is_set (at) then ws_url, ws_label, L = wikisource_url_make (at); -- make ws URL from |at= interwiki link; link portion L becomes tooltip label if ws_url then at = external_link (ws_url, ws_label .. '&nbsp;', 'ws link in at'); -- space char after label to move icon away from in-source text; TODO: a better way to do this? at = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], L, at}); coins_pages = ws_label; end end return page, pages, at, coins_pages; end --[[--------------------------< I S _ U N I Q U E _ A R C H I V E _ U R L >------------------------------------ add error message when |archive-url= value is same as |url= or chapter-url= (or alias...) value ]] local function is_unique_archive_url (archive, url, c_url, source, date) if utilities.is_set (archive) then if archive == url or archive == c_url then utilities.set_message ('err_bad_url', {utilities.wrap_style ('parameter', source)}); -- add error message return '', ''; -- unset |archive-url= and |archive-date= because same as |url= or |chapter-url= end end return archive, date; end --[=[-------------------------< A R C H I V E _ U R L _ C H E C K >-------------------------------------------- Check archive.org URLs to make sure they at least look like they are pointing at valid archives and not to the save snapshot URL or to calendar pages. When the archive URL is 'https://web.archive.org/save/' (or http://...) archive.org saves a snapshot of the target page in the URL. That is something that Wikipedia should not allow unwitting readers to do. When the archive.org URL does not have a complete timestamp, archive.org chooses a snapshot according to its own algorithm or provides a calendar 'search' result. [[WP:ELNO]] discourages links to search results. This function looks at the value assigned to |archive-url= and returns empty strings for |archive-url= and |archive-date= and an error message when: |archive-url= holds an archive.org save command URL |archive-url= is an archive.org URL that does not have a complete timestamp (YYYYMMDDhhmmss 14 digits) in the correct place otherwise returns |archive-url= and |archive-date= There are two mostly compatible archive.org URLs: //web.archive.org/<timestamp>... -- the old form //web.archive.org/web/<timestamp>... -- the new form The old form does not support or map to the new form when it contains a display flag. There are four identified flags ('id_', 'js_', 'cs_', 'im_') but since archive.org ignores others following the same form (two letters and an underscore) we don't check for these specific flags but we do check the form. This function supports a preview mode. When the article is rendered in preview mode, this function may return a modified archive URL: for save command errors, return undated wildcard (/*/) for timestamp errors when the timestamp has a wildcard, return the URL unmodified for timestamp errors when the timestamp does not have a wildcard, return with timestamp limited to six digits plus wildcard (/yyyymm*/) A secondary function is to return an archive-url timestamp from those urls that have them (archive.org and archive.today). The timestamp is used by validation.archive_date_check() to see if the value in |archive-date= matches the timestamp in the archive url. ]=] local function archive_url_check (url, date) local err_msg = ''; -- start with the error message empty local path, timestamp, flag; -- portions of the archive.org URL timestamp = url:match ('//archive.today/(%d%d%d%d%d%d%d%d%d%d%d%d%d%d)/') or -- get timestamp from archive.today urls url:match ('//archive.today/(%d%d%d%d%.%d%d%.%d%d%-%d%d%d%d%d%d)/'); -- this timestamp needs cleanup if timestamp then -- if this was an archive.today url ... return url, date, timestamp:gsub ('[%.%-]', ''); -- return ArchiveURL, ArchiveDate, and timestamp (dots and dashes removed) from |archive-url=, and done -- return ArchiveURL, ArchiveDate, and timestamp from |archive-url=, and done end -- here for archive.org urls if (not url:match('//web%.archive%.org/')) and (not url:match('//liveweb%.archive%.org/')) then -- also deprecated liveweb Wayback machine URL return url, date; -- not an archive.org archive, return ArchiveURL and ArchiveDate end if url:match('//web%.archive%.org/save/') then -- if a save command URL, we don't want to allow saving of the target page err_msg = cfg.err_msg_supl.save; url = url:gsub ('(//web%.archive%.org)/save/', '%1/*/', 1); -- for preview mode: modify ArchiveURL elseif url:match('//liveweb%.archive%.org/') then err_msg = cfg.err_msg_supl.liveweb; else path, timestamp, flag = url:match('//web%.archive%.org/([^%d]*)(%d+)([^/]*)/'); -- split out some of the URL parts for evaluation if not path then -- malformed in some way; pattern did not match err_msg = cfg.err_msg_supl.timestamp; elseif 14 ~= timestamp:len() then -- path and flag optional, must have 14-digit timestamp here err_msg = cfg.err_msg_supl.timestamp; if '*' ~= flag then local replacement = timestamp:match ('^%d%d%d%d%d%d') or timestamp:match ('^%d%d%d%d'); -- get the first 6 (YYYYMM) or first 4 digits (YYYY) if replacement then -- nil if there aren't at least 4 digits (year) replacement = replacement .. string.rep ('0', 14 - replacement:len()); -- year or yearmo (4 or 6 digits) zero-fill to make 14-digit timestamp url=url:gsub ('(//web%.archive%.org/[^%d]*)%d[^/]*', '%1' .. replacement .. '*', 1) -- for preview, modify ts to 14 digits plus splat for calendar display end end elseif utilities.is_set (path) and 'web/' ~= path then -- older archive URLs do not have the extra 'web/' path element err_msg = cfg.err_msg_supl.path; elseif utilities.is_set (flag) and not utilities.is_set (path) then -- flag not allowed with the old form URL (without the 'web/' path element) err_msg = cfg.err_msg_supl.flag; elseif utilities.is_set (flag) and not flag:match ('%a%a_') then -- flag if present must be two alpha characters and underscore (requires 'web/' path element) err_msg = cfg.err_msg_supl.flag; else return url, date, timestamp; -- return ArchiveURL, ArchiveDate, and timestamp from |archive-url= end end -- if here, something not right so utilities.set_message ('err_archive_url', {err_msg}); -- add error message and if is_preview_mode then return url, date, timestamp; -- preview mode so return ArchiveURL, ArchiveDate, and timestamp from |archive-url= else return '', ''; -- return empty strings for ArchiveURL and ArchiveDate end end --[[--------------------------< P L A C E _ C H E C K >-------------------------------------------------------- check |place=, |publication-place=, |location= to see if these params include digits. This function added because many editors misuse location to specify the in-source location (|page(s)= and |at= are supposed to do that) returns the original parameter value without modification; added maint cat when parameter value contains digits ]] local function place_check (param_val) if not utilities.is_set (param_val) then -- parameter empty or omitted return param_val; -- return that empty state end if mw.ustring.find (param_val, '%d') then -- not empty, are there digits in the parameter value utilities.set_message ('maint_location'); -- yep, add maint cat end return param_val; -- and done end --[[--------------------------< I S _ A R C H I V E D _ C O P Y >---------------------------------------------- compares |title= to 'Archived copy' (placeholder added by bots that can't find proper title); if matches, return true; nil else ]] local function is_archived_copy (title) title = mw.ustring.lower(title); -- switch title to lower case if title:find (cfg.special_case_translation.archived_copy.en) then -- if title is 'Archived copy' return true; elseif cfg.special_case_translation.archived_copy['local'] then if mw.ustring.find (title, cfg.special_case_translation.archived_copy['local']) then -- mw.ustring() because might not be Latin script return true; end end end --[[--------------------------< D I S P L A Y _ N A M E S _ S E L E C T >-------------------------------------- for any of the |display-authors=, |display-editors=, etc parameters, select either the local or global setting. When both are present, look at <local_display_names> value. When the value is some sort of 'et al.'string, special handling is required. When {{cs1 config}} has |display-<namelist>= AND this template has |display-<namelist>=etal AND: the number of names specified by <number_of_names> is: greater than the number specified in the global |display-<namelist>= parameter (<global_display_names>) use global |display-<namelist>= parameter value set overridden maint category less than or equal to the number specified in the global |display-<namelist>= parameter use local |display-<namelist>= parameter value The purpose of this function is to prevent categorizing a template that has fewer names than the global setting to keep the etal annotation specified by <local_display_names>. ]] local function display_names_select (global_display_names, local_display_names, param_name, number_of_names, test) if global_display_names and utilities.is_set (local_display_names) then -- when both if 'etal' == local_display_names:lower():gsub("[ '%.]", '') then -- the :gsub() portion makes 'etal' from a variety of 'et al.' spellings and stylings number_of_names = tonumber (number_of_names); -- convert these to numbers for comparison local global_display_names_num = tonumber (global_display_names); -- <global_display_names> not set when parameter value is not digits if number_of_names > global_display_names_num then -- template has more names than global config allows to be displayed? utilities.set_message ('maint_overridden_setting'); -- set a maint message because global is overriding local |display-<namelist>=etal return global_display_names, 'cs1 config'; -- return global with spoof parameter name (for get_display_names()) else return local_display_names, param_name; -- return local because fewer names so let <local_display_names> control end end -- here when <global_display_names> and <local_display_names> both numbers; <global_display_names> controls utilities.set_message ('maint_overridden_setting'); -- set a maint message return global_display_names, 'cs1 config'; -- return global with spoof parameter name (for get_display_names()) end -- here when only one of <global_display_names> or <local_display_names> set if global_display_names then return global_display_names, 'cs1 config'; -- return global with spoof parameter name (for get_display_names()) else return local_display_names, param_name; -- return local end end --[[--------------------------< C I T A T I O N 0 >------------------------------------------------------------ This is the main function doing the majority of the citation formatting. ]] local function citation0( config, args ) --[[ Load Input Parameters The argument_wrapper facilitates the mapping of multiple aliases to single internal variable. ]] local A = argument_wrapper ( args ); local i -- Pick out the relevant fields from the arguments. Different citation templates -- define different field names for the same underlying things. local author_etal; local a = {}; -- authors list from |lastn= / |firstn= pairs or |vauthors= local Authors; local NameListStyle; if cfg.global_cs1_config_t['NameListStyle'] then -- global setting in {{cs1 config}} overrides local |name-list-style= parameter value; nil when empty or assigned value invalid NameListStyle = is_valid_parameter_value (cfg.global_cs1_config_t['NameListStyle'], 'cs1 config: name-list-style', cfg.keywords_lists['name-list-style'], ''); -- error messaging 'param' here is a hoax else NameListStyle = is_valid_parameter_value (A['NameListStyle'], A:ORIGIN('NameListStyle'), cfg.keywords_lists['name-list-style'], ''); end if cfg.global_cs1_config_t['NameListStyle'] and utilities.is_set (A['NameListStyle']) then -- when template has |name-list-style=<something> which global setting has overridden utilities.set_message ('maint_overridden_setting'); -- set a maint message end local Collaboration = A['Collaboration']; do -- to limit scope of selected local selected = select_author_editor_source (A['Vauthors'], A['Authors'], args, 'AuthorList'); if 1 == selected then a, author_etal = extract_names (args, 'AuthorList'); -- fetch author list from |authorn= / |lastn= / |firstn=, |author-linkn=, and |author-maskn= elseif 2 == selected then NameListStyle = 'vanc'; -- override whatever |name-list-style= might be a, author_etal = parse_vauthors_veditors (args, A['Vauthors'], 'AuthorList'); -- fetch author list from |vauthors=, |author-linkn=, and |author-maskn= elseif 3 == selected then Authors = A['Authors']; -- use content of |authors= end if utilities.is_set (Collaboration) then author_etal = true; -- so that |display-authors=etal not required end end local editor_etal; local e = {}; -- editors list from |editor-lastn= / |editor-firstn= pairs or |veditors= do -- to limit scope of selected local selected = select_author_editor_source (A['Veditors'], nil, args, 'EditorList'); -- support for |editors= withdrawn if 1 == selected then e, editor_etal = extract_names (args, 'EditorList'); -- fetch editor list from |editorn= / |editor-lastn= / |editor-firstn=, |editor-linkn=, and |editor-maskn= elseif 2 == selected then NameListStyle = 'vanc'; -- override whatever |name-list-style= might be e, editor_etal = parse_vauthors_veditors (args, args.veditors, 'EditorList'); -- fetch editor list from |veditors=, |editor-linkn=, and |editor-maskn= end end local Chapter = A['Chapter']; -- done here so that we have access to |contribution= from |chapter= aliases local Chapter_origin = A:ORIGIN ('Chapter'); local Contribution; -- because contribution is required for contributor(s) if 'contribution' == Chapter_origin then Contribution = Chapter; -- get the name of the contribution end local c = {}; -- contributors list from |contributor-lastn= / contributor-firstn= pairs if utilities.in_array (config.CitationClass, {"book", "citation"}) and not utilities.is_set (A['Periodical']) then -- |contributor= and |contribution= only supported in book cites c = extract_names (args, 'ContributorList'); -- fetch contributor list from |contributorn= / |contributor-lastn=, -firstn=, -linkn=, -maskn= if 0 < #c then if not utilities.is_set (Contribution) then -- |contributor= requires |contribution= utilities.set_message ('err_contributor_missing_required_param', 'contribution'); -- add missing contribution error message c = {}; -- blank the contributors' table; it is used as a flag later end if 0 == #a then -- |contributor= requires |author= utilities.set_message ('err_contributor_missing_required_param', 'author'); -- add missing author error message c = {}; -- blank the contributors' table; it is used as a flag later end end else -- if not a book cite if utilities.select_one (args, cfg.aliases['ContributorList-Last'], 'err_redundant_parameters', 1 ) then -- are there contributor name list parameters? utilities.set_message ('err_contributor_ignored'); -- add contributor ignored error message end Contribution = nil; -- unset end local Title = A['Title']; local TitleLink = A['TitleLink']; local auto_select = ''; -- default is auto local accept_link; TitleLink, accept_link = utilities.has_accept_as_written (TitleLink, true); -- test for accept-this-as-written markup if (not accept_link) and utilities.in_array (TitleLink, {'none', 'pmc', 'doi'}) then -- check for special keywords auto_select = TitleLink; -- remember selection for later TitleLink = ''; -- treat as if |title-link= would have been empty end TitleLink = link_title_ok (TitleLink, A:ORIGIN ('TitleLink'), Title, 'title'); -- check for wiki-markup in |title-link= or wiki-markup in |title= when |title-link= is set local Section = ''; -- {{cite map}} only; preset to empty string for concatenation if not used if 'map' == config.CitationClass and 'section' == Chapter_origin then Section = A['Chapter']; -- get |section= from |chapter= alias list; |chapter= and the other aliases not supported in {{cite map}} Chapter = ''; -- unset for now; will be reset later from |map= if present end local Periodical = A['Periodical']; local Periodical_origin = A:ORIGIN('Periodical'); local ScriptPeriodical = A['ScriptPeriodical']; local ScriptPeriodical_origin = A:ORIGIN('ScriptPeriodical'); local TransPeriodical = A['TransPeriodical']; local TransPeriodical_origin = A:ORIGIN ('TransPeriodical'); if (utilities.in_array (config.CitationClass, {'book', 'encyclopaedia'}) and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical) or utilities.is_set (TransPeriodical))) then local param; if utilities.is_set (Periodical) then -- get a parameter name from one of these periodical related meta-parameters Periodical = ''; -- unset because not valid {{cite book}} or {{cite encyclopedia}} parameters param = Periodical_origin -- get parameter name for error messaging elseif utilities.is_set (TransPeriodical) then TransPeriodical = ''; -- unset because not valid {{cite book}} or {{cite encyclopedia}} parameters param = TransPeriodical_origin; -- get parameter name for error messaging elseif utilities.is_set (ScriptPeriodical) then ScriptPeriodical = ''; -- unset because not valid {{cite book}} or {{cite encyclopedia}} parameters param = ScriptPeriodical_origin; -- get parameter name for error messaging end if utilities.is_set (param) then -- if we found one utilities.set_message ('err_periodical_ignored', {param}); -- emit an error message end end if utilities.is_set (Periodical) then local i; Periodical, i = utilities.strip_apostrophe_markup (Periodical); -- strip apostrophe markup so that metadata isn't contaminated if i then -- non-zero when markup was stripped so emit an error message utilities.set_message ('err_apostrophe_markup', {Periodical_origin}); end end if 'mailinglist' == config.CitationClass then -- special case for {{cite mailing list}} if utilities.is_set (Periodical) and utilities.is_set (A ['MailingList']) then -- both set emit an error TODO: make a function for this and similar? utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', Periodical_origin) .. cfg.presentation['sep_list_pair'] .. utilities.wrap_style ('parameter', 'mailinglist')}); end Periodical = A ['MailingList']; -- error or no, set Periodical to |mailinglist= value because this template is {{cite mailing list}} Periodical_origin = A:ORIGIN('MailingList'); end -- web and news not tested for now because of -- Wikipedia:Administrators%27_noticeboard#Is_there_a_semi-automated_tool_that_could_fix_these_annoying_"Cite_Web"_errors? if not (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) then -- 'periodical' templates require periodical parameter -- local p = {['journal'] = 'journal', ['magazine'] = 'magazine', ['news'] = 'newspaper', ['web'] = 'website'}; -- for error message local p = {['journal'] = 'journal', ['magazine'] = 'magazine'}; -- for error message if p[config.CitationClass] then utilities.set_message ('err_missing_periodical', {config.CitationClass, p[config.CitationClass]}); end end local Volume; if 'citation' == config.CitationClass then if utilities.is_set (Periodical) then if not utilities.in_array (Periodical_origin, cfg.citation_no_volume_t) then -- {{citation}} does not render |volume= when these parameters are used Volume = A['Volume']; -- but does for all other 'periodicals' end elseif utilities.is_set (ScriptPeriodical) then if 'script-website' ~= ScriptPeriodical_origin then -- {{citation}} does not render volume for |script-website= Volume = A['Volume']; -- but does for all other 'periodicals' end else Volume = A['Volume']; -- and does for non-'periodical' cites end elseif utilities.in_array (config.CitationClass, cfg.templates_using_volume) then -- render |volume= for cs1 according to the configuration settings Volume = A['Volume']; end extra_text_in_vol_iss_check (Volume, A:ORIGIN ('Volume'), 'v'); local Issue; if 'citation' == config.CitationClass then if utilities.is_set (Periodical) and utilities.in_array (Periodical_origin, cfg.citation_issue_t) then -- {{citation}} may render |issue= when these parameters are used Issue = utilities.hyphen_to_dash (A['Issue']); end elseif utilities.in_array (config.CitationClass, cfg.templates_using_issue) then -- conference & map books do not support issue; {{citation}} listed here because included in settings table if not (utilities.in_array (config.CitationClass, {'conference', 'map', 'citation'}) and not (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical))) then Issue = utilities.hyphen_to_dash (A['Issue']); end end local ArticleNumber; if utilities.in_array (config.CitationClass, {'journal', 'conference'}) or ('citation' == config.CitationClass and utilities.is_set (Periodical) and 'journal' == Periodical_origin) then ArticleNumber = A['ArticleNumber']; end extra_text_in_vol_iss_check (Issue, A:ORIGIN ('Issue'), 'i'); local Page; local Pages; local At; local QuotePage; local QuotePages; if not utilities.in_array (config.CitationClass, cfg.templates_not_using_page) then -- TODO: rewrite to emit ignored parameter error message? Page = A['Page']; Pages = utilities.hyphen_to_dash (A['Pages']); At = A['At']; QuotePage = A['QuotePage']; QuotePages = utilities.hyphen_to_dash (A['QuotePages']); end local Edition = A['Edition']; local PublicationPlace = place_check (A['PublicationPlace'], A:ORIGIN('PublicationPlace')); local Place = place_check (A['Place'], A:ORIGIN('Place')); local PublisherName = A['PublisherName']; local PublisherName_origin = A:ORIGIN('PublisherName'); if utilities.is_set (PublisherName) and (cfg.keywords_xlate['none'] ~= PublisherName) then local i = 0; PublisherName, i = utilities.strip_apostrophe_markup (PublisherName); -- strip apostrophe markup so that metadata isn't contaminated; publisher is never italicized if i and (0 < i) then -- non-zero when markup was stripped so emit an error message utilities.set_message ('err_apostrophe_markup', {PublisherName_origin}); end end if ('document' == config.CitationClass) and not utilities.is_set (PublisherName) then utilities.set_message ('err_missing_publisher', {config.CitationClass, 'publisher'}); end local Newsgroup = A['Newsgroup']; -- TODO: strip apostrophe markup? local Newsgroup_origin = A:ORIGIN('Newsgroup'); if 'newsgroup' == config.CitationClass then if utilities.is_set (PublisherName) and (cfg.keywords_xlate['none'] ~= PublisherName) then -- general use parameter |publisher= not allowed in cite newsgroup utilities.set_message ('err_parameter_ignored', {PublisherName_origin}); end PublisherName = nil; -- ensure that this parameter is unset for the time being; will be used again after COinS end local URL = A['URL']; -- TODO: better way to do this for URL, ChapterURL, and MapURL? local UrlAccess = is_valid_parameter_value (A['UrlAccess'], A:ORIGIN('UrlAccess'), cfg.keywords_lists['url-access'], nil); if not utilities.is_set (URL) and utilities.is_set (UrlAccess) then UrlAccess = nil; utilities.set_message ('err_param_access_requires_param', 'url'); end local ChapterURL = A['ChapterURL']; local ChapterUrlAccess = is_valid_parameter_value (A['ChapterUrlAccess'], A:ORIGIN('ChapterUrlAccess'), cfg.keywords_lists['url-access'], nil); if not utilities.is_set (ChapterURL) and utilities.is_set (ChapterUrlAccess) then ChapterUrlAccess = nil; utilities.set_message ('err_param_access_requires_param', {A:ORIGIN('ChapterUrlAccess'):gsub ('%-access', '')}); end local MapUrlAccess = is_valid_parameter_value (A['MapUrlAccess'], A:ORIGIN('MapUrlAccess'), cfg.keywords_lists['url-access'], nil); if not utilities.is_set (A['MapURL']) and utilities.is_set (MapUrlAccess) then MapUrlAccess = nil; utilities.set_message ('err_param_access_requires_param', {'map-url'}); end local this_page = mw.title.getCurrentTitle(); -- also used for COinS and for language local no_tracking_cats = is_valid_parameter_value (A['NoTracking'], A:ORIGIN('NoTracking'), cfg.keywords_lists['yes_true_y'], nil); -- check this page to see if it is in one of the namespaces that cs1 is not supposed to add to the error categories if not utilities.is_set (no_tracking_cats) then -- ignore if we are already not going to categorize this page if cfg.uncategorized_namespaces[this_page.namespace] then -- is this page's namespace id one of the uncategorized namespace ids? no_tracking_cats = "true"; -- set no_tracking_cats end for _, v in ipairs (cfg.uncategorized_subpages) do -- cycle through page name patterns if this_page.text:match (v) then -- test page name against each pattern no_tracking_cats = "true"; -- set no_tracking_cats break; -- bail out if one is found end end end -- no_tracking_cats = "true"; -- выключаем всю категоризацию для РУВИКИ -- check for extra |page=, |pages= or |at= parameters. (also sheet and sheets while we're at it) utilities.select_one (args, {'page', 'p', 'pp', 'pages', 'at', 'sheet', 'sheets'}, 'err_redundant_parameters'); -- this is a dummy call simply to get the error message and category local coins_pages; Page, Pages, At, coins_pages = insource_loc_get (Page, A:ORIGIN('Page'), Pages, A:ORIGIN('Pages'), At); local NoPP = is_valid_parameter_value (A['NoPP'], A:ORIGIN('NoPP'), cfg.keywords_lists['yes_true_y'], nil); if utilities.is_set (PublicationPlace) and utilities.is_set (Place) then -- both |publication-place= and |place= (|location=) allowed if different utilities.add_prop_cat ('location-test'); -- add property cat to evaluate how often PublicationPlace and Place are used together if PublicationPlace == Place then Place = ''; -- unset; don't need both if they are the same end elseif not utilities.is_set (PublicationPlace) and utilities.is_set (Place) then -- when only |place= (|location=) is set ... PublicationPlace = Place; -- promote |place= (|location=) to |publication-place end if PublicationPlace == Place then Place = ''; end -- don't need both if they are the same local URL_origin = A:ORIGIN('URL'); -- get name of parameter that holds URL local ChapterURL_origin = A:ORIGIN('ChapterURL'); -- get name of parameter that holds ChapterURL local ScriptChapter = A['ScriptChapter']; local ScriptChapter_origin = A:ORIGIN ('ScriptChapter'); local Format = A['Format']; local ChapterFormat = A['ChapterFormat']; local TransChapter = A['TransChapter']; local TransChapter_origin = A:ORIGIN ('TransChapter'); local TransTitle = A['TransTitle']; local ScriptTitle = A['ScriptTitle']; --[[ Parameter remapping for cite encyclopedia: When the citation has these parameters: |encyclopedia= and |title= then map |title= to |article= and |encyclopedia= to |title= for rendering |encyclopedia= and |article= then map |encyclopedia= to |title= for rendering |trans-title= maps to |trans-chapter= when |title= is re-mapped |url= maps to |chapter-url= when |title= is remapped All other combinations of |encyclopedia=, |title=, and |article= are not modified ]] local Encyclopedia = A['Encyclopedia']; -- used as a flag by this module and by ~/COinS local ScriptEncyclopedia = A['ScriptEncyclopedia']; local TransEncyclopedia = A['TransEncyclopedia']; if utilities.is_set (Encyclopedia) or utilities.is_set (ScriptEncyclopedia) then -- emit error message when Encyclopedia set but template is other than {{cite encyclopedia}} or {{citation}} if 'encyclopaedia' ~= config.CitationClass and 'citation' ~= config.CitationClass then if utilities.is_set (Encyclopedia) then utilities.set_message ('err_parameter_ignored', {A:ORIGIN ('Encyclopedia')}); else utilities.set_message ('err_parameter_ignored', {A:ORIGIN ('ScriptEncyclopedia')}); end Encyclopedia = nil; -- unset these because not supported by this template ScriptEncyclopedia = nil; TransEncyclopedia = nil; end elseif utilities.is_set (TransEncyclopedia) then utilities.set_message ('err_trans_missing_title', {'encyclopedia'}); end if ('encyclopaedia' == config.CitationClass) or ('citation' == config.CitationClass and utilities.is_set (Encyclopedia)) then if utilities.is_set (Periodical) and utilities.is_set (Encyclopedia) then -- when both parameters set emit an error message; {{citation}} only; Periodical not allowed in {{cite encyclopedia}} utilities.set_message ('err_periodical_ignored', {Periodical_origin}); end if utilities.is_set (Encyclopedia) or utilities.is_set (ScriptEncyclopedia) then Periodical = Encyclopedia; -- error or no, set Periodical to Encyclopedia for rendering; {{citation}} could (not legitimately) have both; use Encyclopedia Periodical_origin = A:ORIGIN ('Encyclopedia'); ScriptPeriodical = ScriptEncyclopedia; ScriptPeriodical_origin = A:ORIGIN ('ScriptEncyclopedia'); if utilities.is_set (Title) or utilities.is_set (ScriptTitle) then if not utilities.is_set (Chapter) then Chapter = Title; -- |encyclopedia= and |title= are set so map |title= params to |article= params for rendering ScriptChapter = ScriptTitle; ScriptChapter_origin = A:ORIGIN('ScriptTitle') TransChapter = TransTitle; ChapterURL = URL; ChapterURL_origin = URL_origin; ChapterUrlAccess = UrlAccess; ChapterFormat = Format; if not utilities.is_set (ChapterURL) and utilities.is_set (TitleLink) then Chapter = utilities.make_wikilink (TitleLink, Chapter); end Title = Periodical; -- now map |encyclopedia= params to |title= params for rendering ScriptTitle = ScriptPeriodical or ''; TransTitle = TransEncyclopedia or ''; Periodical = ''; -- redundant so unset ScriptPeriodical = ''; URL = ''; Format = ''; TitleLink = ''; end elseif utilities.is_set (Chapter) or utilities.is_set (ScriptChapter) then -- |title= not set Title = Periodical; -- |encyclopedia= set and |article= set so map |encyclopedia= to |title= for rendering ScriptTitle = ScriptPeriodical or ''; TransTitle = TransEncyclopedia or ''; Periodical = ''; -- redundant so unset ScriptPeriodical = ''; end end end -- special case for cite techreport. local ID = A['ID']; if (config.CitationClass == "techreport") then -- special case for cite techreport if utilities.is_set (A['Number']) then -- cite techreport uses 'number', which other citations alias to 'issue' if not utilities.is_set (ID) then -- can we use ID for the "number"? ID = A['Number']; -- yes, use it else -- ID has a value so emit error message utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', 'id') .. cfg.presentation['sep_list_pair'] .. utilities.wrap_style ('parameter', 'number')}); end end end -- Account for the oddity that is {{cite conference}}, before generation of COinS data. local ChapterLink -- = A['ChapterLink']; -- deprecated as a parameter but still used internally by cite episode local Conference = A['Conference']; local BookTitle = A['BookTitle']; local TransTitle_origin = A:ORIGIN ('TransTitle'); if 'conference' == config.CitationClass then if utilities.is_set (BookTitle) then Chapter = Title; Chapter_origin = 'title'; -- ChapterLink = TitleLink; -- |chapter-link= is deprecated ChapterURL = URL; ChapterUrlAccess = UrlAccess; ChapterURL_origin = URL_origin; URL_origin = ''; ChapterFormat = Format; TransChapter = TransTitle; TransChapter_origin = TransTitle_origin; Title = BookTitle; Format = ''; -- TitleLink = ''; TransTitle = ''; URL = ''; end elseif 'speech' ~= config.CitationClass then Conference = ''; -- not cite conference or cite speech so make sure this is empty string end -- CS1/2 mode local Mode; if cfg.global_cs1_config_t['Mode'] then -- global setting in {{cs1 config}} overrides local |mode= parameter value; nil when empty or assigned value invalid Mode = is_valid_parameter_value (cfg.global_cs1_config_t['Mode'], 'cs1 config: mode', cfg.keywords_lists['mode'], ''); -- error messaging 'param' here is a hoax else Mode = is_valid_parameter_value (A['Mode'], A:ORIGIN('Mode'), cfg.keywords_lists['mode'], ''); end if cfg.global_cs1_config_t['Mode'] and utilities.is_set (A['Mode']) then -- when template has |mode=<something> which global setting has overridden utilities.set_message ('maint_overridden_setting'); -- set a maint message end -- separator character and postscript local sepc, PostScript = set_style (Mode:lower(), A['PostScript'], config.CitationClass); -- controls capitalization of certain static text local use_lowercase = ( sepc == ',' ); -- cite map oddities local Cartography = ""; local Scale = ""; local Sheet = A['Sheet'] or ''; local Sheets = A['Sheets'] or ''; if config.CitationClass == "map" then if utilities.is_set (Chapter) then --TODO: make a function for this and similar? utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', 'map') .. cfg.presentation['sep_list_pair'] .. utilities.wrap_style ('parameter', Chapter_origin)}); -- add error message end Chapter = A['Map']; Chapter_origin = A:ORIGIN('Map'); ChapterURL = A['MapURL']; ChapterURL_origin = A:ORIGIN('MapURL'); TransChapter = A['TransMap']; ScriptChapter = A['ScriptMap'] ScriptChapter_origin = A:ORIGIN('ScriptMap') ChapterUrlAccess = MapUrlAccess; ChapterFormat = A['MapFormat']; Cartography = A['Cartography']; if utilities.is_set ( Cartography ) then Cartography = sepc .. " " .. wrap_msg ('cartography', Cartography, use_lowercase); end Scale = A['Scale']; if utilities.is_set ( Scale ) then Scale = sepc .. " " .. Scale; end end -- Account for the oddities that are {{cite episode}} and {{cite serial}}, before generation of COinS data. local Series = A['Series']; if 'episode' == config.CitationClass or 'serial' == config.CitationClass then local SeriesLink = A['SeriesLink']; SeriesLink = link_title_ok (SeriesLink, A:ORIGIN ('SeriesLink'), Series, 'series'); -- check for wiki-markup in |series-link= or wiki-markup in |series= when |series-link= is set local Network = A['Network']; local Station = A['Station']; local s, n = {}, {}; -- do common parameters first if utilities.is_set (Network) then table.insert(n, Network); end if utilities.is_set (Station) then table.insert(n, Station); end ID = table.concat(n, sepc .. ' '); if 'episode' == config.CitationClass then -- handle the oddities that are strictly {{cite episode}} local Season = A['Season']; local SeriesNumber = A['SeriesNumber']; if utilities.is_set (Season) and utilities.is_set (SeriesNumber) then -- these are mutually exclusive so if both are set TODO: make a function for this and similar? utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', 'season') .. cfg.presentation['sep_list_pair'] .. utilities.wrap_style ('parameter', 'seriesno')}); -- add error message SeriesNumber = ''; -- unset; prefer |season= over |seriesno= end -- assemble a table of parts concatenated later into Series if utilities.is_set (Season) then table.insert(s, wrap_msg ('season', Season, use_lowercase)); end if utilities.is_set (SeriesNumber) then table.insert(s, wrap_msg ('seriesnum', SeriesNumber, use_lowercase)); end if utilities.is_set (Issue) then table.insert(s, wrap_msg ('episode', Issue, use_lowercase)); end Issue = ''; -- unset because this is not a unique parameter Chapter = Title; -- promote title parameters to chapter ScriptChapter = ScriptTitle; ScriptChapter_origin = A:ORIGIN('ScriptTitle'); ChapterLink = TitleLink; -- alias |episode-link= TransChapter = TransTitle; ChapterURL = URL; ChapterUrlAccess = UrlAccess; ChapterURL_origin = URL_origin; ChapterFormat = Format; Title = Series; -- promote series to title TitleLink = SeriesLink; Series = table.concat(s, sepc .. ' '); -- this is concatenation of season, seriesno, episode number if utilities.is_set (ChapterLink) and not utilities.is_set (ChapterURL) then -- link but not URL Chapter = utilities.make_wikilink (ChapterLink, Chapter); elseif utilities.is_set (ChapterLink) and utilities.is_set (ChapterURL) then -- if both are set, URL links episode; Series = utilities.make_wikilink (ChapterLink, Series); end URL = ''; -- unset TransTitle = ''; ScriptTitle = ''; Format = ''; else -- now oddities that are cite serial Issue = ''; -- unset because this parameter no longer supported by the citation/core version of cite serial Chapter = A['Episode']; -- TODO: make |episode= available to cite episode someday? if utilities.is_set (Series) and utilities.is_set (SeriesLink) then Series = utilities.make_wikilink (SeriesLink, Series); end Series = utilities.wrap_style ('italic-title', Series); -- series is italicized end end -- end of {{cite episode}} stuff -- handle type parameter for those CS1 citations that have default values local TitleType = A['TitleType']; local Degree = A['Degree']; if utilities.in_array (config.CitationClass, {'AV-media-notes', 'document', 'interview', 'mailinglist', 'map', 'podcast', 'pressrelease', 'report', 'speech', 'techreport', 'thesis'}) then TitleType = set_titletype (config.CitationClass, TitleType); if utilities.is_set (Degree) and "Thesis" == TitleType then -- special case for cite thesis TitleType = Degree .. ' ' .. cfg.title_types ['thesis']:lower(); end end if utilities.is_set (TitleType) then -- if type parameter is specified TitleType = utilities.substitute ( cfg.messages['type'], TitleType); -- display it in parentheses -- TODO: Hack on TitleType to fix bunched parentheses problem end -- legacy: promote PublicationDate to Date if neither Date nor Year are set. local Date = A['Date']; local Date_origin; -- to hold the name of parameter promoted to Date; required for date error messaging local PublicationDate = A['PublicationDate']; local Year = A['Year']; if not utilities.is_set (Date) then Date = Year; -- promote Year to Date Year = nil; -- make nil so Year as empty string isn't used for CITEREF if not utilities.is_set (Date) and utilities.is_set (PublicationDate) then -- use PublicationDate when |date= and |year= are not set Date = PublicationDate; -- promote PublicationDate to Date PublicationDate = ''; -- unset, no longer needed Date_origin = A:ORIGIN('PublicationDate'); -- save the name of the promoted parameter else Date_origin = A:ORIGIN('Year'); -- save the name of the promoted parameter end else Date_origin = A:ORIGIN('Date'); -- not a promotion; name required for error messaging end if PublicationDate == Date then PublicationDate = ''; end -- if PublicationDate is same as Date, don't display in rendered citation --[[ Go test all of the date-holding parameters for valid MOS:DATE format and make sure that dates are real dates. This must be done before we do COinS because here is where we get the date used in the metadata. Date validation supporting code is in Module:Citation/CS1/Date_validation ]] local DF = is_valid_parameter_value (A['DF'], A:ORIGIN('DF'), cfg.keywords_lists['df'], ''); if not utilities.is_set (DF) then DF = cfg.global_df; -- local |df= if present overrides global df set by {{use xxx date}} template end local ArchiveURL; local ArchiveDate; local ArchiveFormat = A['ArchiveFormat']; local archive_url_timestamp; -- timestamp from wayback machine url ArchiveURL, ArchiveDate, archive_url_timestamp = archive_url_check (A['ArchiveURL'], A['ArchiveDate']) ArchiveFormat = style_format (ArchiveFormat, ArchiveURL, 'archive-format', 'archive-url'); ArchiveURL, ArchiveDate = is_unique_archive_url (ArchiveURL, URL, ChapterURL, A:ORIGIN('ArchiveURL'), ArchiveDate); -- add error message when URL or ChapterURL == ArchiveURL local AccessDate = A['AccessDate']; local COinS_date = {}; -- holds date info extracted from |date= for the COinS metadata by Module:Date verification local DoiBroken = A['DoiBroken']; local Embargo = A['Embargo']; local anchor_year; -- used in the CITEREF identifier do -- create defined block to contain local variables error_message, date_parameters_list, mismatch local error_message = ''; -- AirDate has been promoted to Date so not necessary to check it local date_parameters_list = { ['access-date'] = {val = AccessDate, name = A:ORIGIN ('AccessDate')}, ['archive-date'] = {val = ArchiveDate, name = A:ORIGIN ('ArchiveDate')}, ['date'] = {val = Date, name = Date_origin}, ['doi-broken-date'] = {val = DoiBroken, name = A:ORIGIN ('DoiBroken')}, ['pmc-embargo-date'] = {val = Embargo, name = A:ORIGIN ('Embargo')}, ['publication-date'] = {val = PublicationDate, name = A:ORIGIN ('PublicationDate')}, ['year'] = {val = Year, name = A:ORIGIN ('Year')}, }; local error_list = {}; anchor_year, Embargo = validation.dates(date_parameters_list, COinS_date, error_list); if utilities.is_set (Year) and utilities.is_set (Date) then -- both |date= and |year= not normally needed; validation.year_date_check (Year, A:ORIGIN ('Year'), Date, A:ORIGIN ('Date'), error_list); end if 0 == #error_list then -- error free dates only; 0 when error_list is empty local modified = false; -- flag if utilities.is_set (DF) then -- if we need to reformat dates modified = validation.reformat_dates (date_parameters_list, DF); -- reformat to DF format, use long month names if appropriate end if true == validation.date_hyphen_to_dash (date_parameters_list) then -- convert hyphens to dashes where appropriate modified = true; utilities.set_message ('maint_date_format'); -- hyphens were converted so add maint category end -- for those wikis that can and want to have English date names translated to the local language; not supported at en.wiki if cfg.date_name_auto_xlate_enable and validation.date_name_xlate (date_parameters_list, cfg.date_digit_auto_xlate_enable ) then utilities.set_message ('maint_date_auto_xlated'); -- add maint cat modified = true; end if modified then -- if the date_parameters_list values were modified AccessDate = date_parameters_list['access-date'].val; -- overwrite date holding parameters with modified values ArchiveDate = date_parameters_list['archive-date'].val; Date = date_parameters_list['date'].val; DoiBroken = date_parameters_list['doi-broken-date'].val; PublicationDate = date_parameters_list['publication-date'].val; end if archive_url_timestamp and utilities.is_set (ArchiveDate) then validation.archive_date_check (ArchiveDate, archive_url_timestamp, DF); -- does YYYYMMDD in archive_url_timestamp match date in ArchiveDate end else utilities.set_message ('err_bad_date', {utilities.make_sep_list (#error_list, error_list)}); -- add this error message end end -- end of do if utilities.in_array (config.CitationClass, {'book', 'encyclopaedia'}) or -- {{cite book}}, {{cite encyclopedia}}; TODO: {{cite conference}} and others? ('citation' == config.CitationClass and utilities.is_set (Encyclopedia)) or -- {{citation}} as an encylopedia citation ('citation' == config.CitationClass and not utilities.is_set (Periodical)) then -- {{citation}} as a book citation if utilities.is_set (PublicationPlace) then if not utilities.is_set (PublisherName) then local date = COinS_date.rftdate and tonumber (COinS_date.rftdate:match ('%d%d%d%d')); -- get year portion of COinS date (because in Arabic numerals); convert string to number if date and (1850 <= date) then -- location has no publisher; if date is 1850 or later utilities.set_message ('maint_location_no_publisher'); -- add maint cat end else -- PublisherName has a value if cfg.keywords_xlate['none'] == PublisherName then -- if that value is 'none' (only for book and encyclopedia citations) PublisherName = ''; -- unset end end end end local ID_list = {}; -- sequence table of rendered identifiers local ID_list_coins = {}; -- table of identifiers and their values from args; key is same as cfg.id_handlers's key local Class = A['Class']; -- arxiv class identifier local ID_support = { {A['ASINTLD'], 'ASIN', 'err_asintld_missing_asin', A:ORIGIN ('ASINTLD')}, {DoiBroken, 'DOI', 'err_doibroken_missing_doi', A:ORIGIN ('DoiBroken')}, {Embargo, 'PMC', 'err_embargo_missing_pmc', A:ORIGIN ('Embargo')}, } ID_list, ID_list_coins = identifiers.identifier_lists_get (args, {DoiBroken = DoiBroken, ASINTLD = A['ASINTLD'], Embargo = Embargo, Class = Class}, ID_support); -- Account for the oddities that are {{cite arxiv}}, {{cite biorxiv}}, {{cite citeseerx}}, {{cite medrxiv}}, {{cite ssrn}}, before generation of COinS data. if utilities.in_array (config.CitationClass, whitelist.preprint_template_list_t) then -- |arxiv= or |eprint= required for cite arxiv; |biorxiv=, |citeseerx=, |medrxiv=, |ssrn= required for their templates if not (args[cfg.id_handlers[config.CitationClass:upper()].parameters[1]] or -- can't use ID_list_coins k/v table here because invalid parameters omitted args[cfg.id_handlers[config.CitationClass:upper()].parameters[2]]) then -- which causes unexpected parameter missing error message utilities.set_message ('err_' .. config.CitationClass .. '_missing'); -- add error message end Periodical = ({['arxiv'] = 'arXiv', ['biorxiv'] = 'bioRxiv', ['citeseerx'] = 'CiteSeerX', ['medrxiv'] = 'medRxiv', ['ssrn'] = 'Social Science Research Network'})[config.CitationClass]; end -- Link the title of the work if no |url= was provided, but we have a |pmc= or a |doi= with |doi-access=free if config.CitationClass == "journal" and not utilities.is_set (URL) and not utilities.is_set (TitleLink) and not utilities.in_array (cfg.keywords_xlate[Title], {'off', 'none'}) then -- TODO: remove 'none' once existing citations have been switched to 'off', so 'none' can be used as token for "no title" instead if 'none' ~= cfg.keywords_xlate[auto_select] then -- if auto-linking not disabled if identifiers.auto_link_urls[auto_select] then -- manual selection URL = identifiers.auto_link_urls[auto_select]; -- set URL to be the same as identifier's external link URL_origin = cfg.id_handlers[auto_select:upper()].parameters[1]; -- set URL_origin to parameter name for use in error message if citation is missing a |title= elseif identifiers.auto_link_urls['pmc'] then -- auto-select PMC URL = identifiers.auto_link_urls['pmc']; -- set URL to be the same as the PMC external link if not embargoed URL_origin = cfg.id_handlers['PMC'].parameters[1]; -- set URL_origin to parameter name for use in error message if citation is missing a |title= elseif identifiers.auto_link_urls['doi'] then -- auto-select DOI URL = identifiers.auto_link_urls['doi']; URL_origin = cfg.id_handlers['DOI'].parameters[1]; end end if utilities.is_set (URL) then -- set when using an identifier-created URL if utilities.is_set (AccessDate) then -- |access-date= requires |url=; identifier-created URL is not |url= utilities.set_message ('err_accessdate_missing_url'); -- add an error message AccessDate = ''; -- unset end if utilities.is_set (ArchiveURL) then -- |archive-url= requires |url=; identifier-created URL is not |url= utilities.set_message ('err_archive_missing_url'); -- add an error message ArchiveURL = ''; -- unset end end end -- At this point fields may be nil if they weren't specified in the template use. We can use that fact. -- Test if citation has no title if not utilities.is_set (Title) and not utilities.is_set (TransTitle) and not utilities.is_set (ScriptTitle) then -- has special case for cite episode utilities.set_message ('err_citation_missing_title', {'episode' == config.CitationClass and 'series' or 'title'}); end if utilities.in_array (cfg.keywords_xlate[Title], {'off', 'none'}) and utilities.in_array (config.CitationClass, {'journal', 'citation'}) and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) and ('journal' == Periodical_origin or 'script-journal' == ScriptPeriodical_origin) then -- special case for journal cites Title = ''; -- set title to empty string utilities.set_message ('maint_untitled'); -- add maint cat end -- COinS metadata (see <http://ocoins.info/>) for automated parsing of citation information. -- handle the oddity that is cite encyclopedia and {{citation |encyclopedia=something}}. Here we presume that -- when Periodical, Title, and Chapter are all set, then Periodical is the book (encyclopedia) title, Title -- is the article title, and Chapter is a section within the article. So, we remap local coins_chapter = Chapter; -- default assuming that remapping not required local coins_title = Title; -- et tu if 'encyclopaedia' == config.CitationClass or ('citation' == config.CitationClass and utilities.is_set (Encyclopedia)) then if utilities.is_set (Chapter) and utilities.is_set (Title) and utilities.is_set (Periodical) then -- if all are used then coins_chapter = Title; -- remap coins_title = Periodical; end end local coins_author = a; -- default for coins rft.au if 0 < #c then -- but if contributor list coins_author = c; -- use that instead end -- this is the function call to COinS() local OCinSoutput = metadata.COinS({ ['Periodical'] = utilities.strip_apostrophe_markup (Periodical), -- no markup in the metadata ['Encyclopedia'] = Encyclopedia, -- just a flag; content ignored by ~/COinS ['Chapter'] = metadata.make_coins_title (coins_chapter, ScriptChapter), -- Chapter and ScriptChapter stripped of bold / italic / accept-as-written markup ['Degree'] = Degree; -- cite thesis only ['Title'] = metadata.make_coins_title (coins_title, ScriptTitle), -- Title and ScriptTitle stripped of bold / italic / accept-as-written markup ['PublicationPlace'] = PublicationPlace, ['Date'] = COinS_date.rftdate, -- COinS_date.* has correctly formatted date values if Date is valid; ['Season'] = COinS_date.rftssn, ['Quarter'] = COinS_date.rftquarter, ['Chron'] = COinS_date.rftchron, ['Series'] = Series, ['Volume'] = Volume, ['Issue'] = Issue, ['ArticleNumber'] = ArticleNumber, ['Pages'] = coins_pages or metadata.get_coins_pages (first_set ({Sheet, Sheets, Page, Pages, At, QuotePage, QuotePages}, 7)), -- pages stripped of external links ['Edition'] = Edition, ['PublisherName'] = PublisherName or Newsgroup, -- any apostrophe markup already removed from PublisherName ['URL'] = first_set ({ChapterURL, URL}, 2), ['Authors'] = coins_author, ['ID_list'] = ID_list_coins, ['RawPage'] = this_page.prefixedText, }, config.CitationClass); -- Account for the oddities that are {{cite arxiv}}, {{cite biorxiv}}, {{cite citeseerx}}, {{cite medrxiv}}, and {{cite ssrn}} AFTER generation of COinS data. if utilities.in_array (config.CitationClass, whitelist.preprint_template_list_t) then -- we have set rft.jtitle in COinS to arXiv, bioRxiv, CiteSeerX, medRxiv, or ssrn now unset so it isn't displayed Periodical = ''; -- periodical not allowed in these templates; if article has been published, use cite journal end -- special case for cite newsgroup. Do this after COinS because we are modifying Publishername to include some static text if 'newsgroup' == config.CitationClass and utilities.is_set (Newsgroup) then PublisherName = utilities.substitute (cfg.messages['newsgroup'], external_link( 'news:' .. Newsgroup, Newsgroup, Newsgroup_origin, nil )); end local Editors; local EditorCount; -- used only for choosing {ed.) or (eds.) annotation at end of editor name-list local Contributors; -- assembled contributors name list local contributor_etal; local Translators; -- assembled translators name list local translator_etal; local t = {}; -- translators list from |translator-lastn= / translator-firstn= pairs t = extract_names (args, 'TranslatorList'); -- fetch translator list from |translatorn= / |translator-lastn=, -firstn=, -linkn=, -maskn= local Interviewers; local interviewers_list = {}; interviewers_list = extract_names (args, 'InterviewerList'); -- process preferred interviewers parameters local interviewer_etal; -- Now perform various field substitutions. -- We also add leading spaces and surrounding markup and punctuation to the -- various parts of the citation, but only when they are non-nil. do local last_first_list; local control = { format = NameListStyle, -- empty string, '&', 'amp', 'and', or 'vanc' maximum = nil, -- as if display-authors or display-editors not set mode = Mode }; do -- do editor name list first because the now unsupported coauthors used to modify control table local display_names, param = display_names_select (cfg.global_cs1_config_t['DisplayEditors'], A['DisplayEditors'], A:ORIGIN ('DisplayEditors'), #e); control.maximum, editor_etal = get_display_names (display_names, #e, 'editors', editor_etal, param); Editors, EditorCount = list_people (control, e, editor_etal); if 1 == EditorCount and (true == editor_etal or 1 < #e) then -- only one editor displayed but includes etal then EditorCount = 2; -- spoof to display (eds.) annotation end end do -- now do interviewers local display_names, param = display_names_select (cfg.global_cs1_config_t['DisplayInterviewers'], A['DisplayInterviewers'], A:ORIGIN ('DisplayInterviewers'), #interviewers_list); control.maximum, interviewer_etal = get_display_names (display_names, #interviewers_list, 'interviewers', interviewer_etal, param); Interviewers = list_people (control, interviewers_list, interviewer_etal); end do -- now do translators local display_names, param = display_names_select (cfg.global_cs1_config_t['DisplayTranslators'], A['DisplayTranslators'], A:ORIGIN ('DisplayTranslators'), #t); control.maximum, translator_etal = get_display_names (display_names, #t, 'translators', translator_etal, param); Translators = list_people (control, t, translator_etal); end do -- now do contributors local display_names, param = display_names_select (cfg.global_cs1_config_t['DisplayContributors'], A['DisplayContributors'], A:ORIGIN ('DisplayContributors'), #c); control.maximum, contributor_etal = get_display_names (display_names, #c, 'contributors', contributor_etal, param); Contributors = list_people (control, c, contributor_etal); end do -- now do authors local display_names, param = display_names_select (cfg.global_cs1_config_t['DisplayAuthors'], A['DisplayAuthors'], A:ORIGIN ('DisplayAuthors'), #a, author_etal); control.maximum, author_etal = get_display_names (display_names, #a, 'authors', author_etal, param); last_first_list = list_people (control, a, author_etal); if utilities.is_set (Authors) then Authors, author_etal = name_has_etal (Authors, author_etal, false, 'authors'); -- find and remove variations on et al. if author_etal then Authors = Authors .. ' ' .. cfg.messages['et al']; -- add et al. to authors parameter end else Authors = last_first_list; -- either an author name list or an empty string end end -- end of do if utilities.is_set (Authors) and utilities.is_set (Collaboration) then Authors = Authors .. ' (' .. Collaboration .. ')'; -- add collaboration after et al. end end local ConferenceFormat = A['ConferenceFormat']; local ConferenceURL = A['ConferenceURL']; ConferenceFormat = style_format (ConferenceFormat, ConferenceURL, 'conference-format', 'conference-url'); Format = style_format (Format, URL, 'format', 'url'); -- special case for chapter format so no error message or cat when chapter not supported if not (utilities.in_array (config.CitationClass, {'web', 'news', 'journal', 'magazine', 'pressrelease', 'podcast', 'newsgroup', 'arxiv', 'biorxiv', 'citeseerx', 'medrxiv', 'ssrn'}) or ('citation' == config.CitationClass and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) and not utilities.is_set (Encyclopedia))) then ChapterFormat = style_format (ChapterFormat, ChapterURL, 'chapter-format', 'chapter-url'); end if not utilities.is_set (URL) then if utilities.in_array (config.CitationClass, {"web", "podcast", "mailinglist"}) or -- |url= required for cite web, cite podcast, and cite mailinglist ('citation' == config.CitationClass and ('website' == Periodical_origin or 'script-website' == ScriptPeriodical_origin)) then -- and required for {{citation}} with |website= or |script-website= utilities.set_message ('err_cite_web_url'); end -- do we have |accessdate= without either |url= or |chapter-url=? if utilities.is_set (AccessDate) and not utilities.is_set (ChapterURL) then -- ChapterURL may be set when URL is not set; utilities.set_message ('err_accessdate_missing_url'); AccessDate = ''; end end local UrlStatus = is_valid_parameter_value (A['UrlStatus'], A:ORIGIN('UrlStatus'), cfg.keywords_lists['url-status'], ''); local OriginalURL local OriginalURL_origin local OriginalFormat local OriginalAccess; UrlStatus = UrlStatus:lower(); -- used later when assembling archived text if utilities.is_set ( ArchiveURL ) then if utilities.is_set (ChapterURL) then -- if chapter-url= is set apply archive url to it OriginalURL = ChapterURL; -- save copy of source chapter's url for archive text OriginalURL_origin = ChapterURL_origin; -- name of |chapter-url= parameter for error messages OriginalFormat = ChapterFormat; -- and original |chapter-format= if utilities.in_array (UrlStatus, {'unfit', 'deviated', 'dead', 'usurped', 'bot: unknown'}) then ChapterURL = ArchiveURL -- swap-in the archive's URL ChapterURL_origin = A:ORIGIN('ArchiveURL') -- name of |archive-url= parameter for error messages ChapterFormat = ArchiveFormat or ''; -- swap in archive's format ChapterUrlAccess = nil; -- restricted access levels do not make sense for archived URLs end elseif utilities.is_set (URL) then OriginalURL = URL; -- save copy of original source URL OriginalURL_origin = URL_origin; -- name of URL parameter for error messages OriginalFormat = Format; -- and original |format= OriginalAccess = UrlAccess; if utilities.in_array (UrlStatus, {'unfit', 'deviated', 'dead', 'usurped', 'bot: unknown'}) then -- if URL set then |archive-url= applies to it URL = ArchiveURL -- swap-in the archive's URL URL_origin = A:ORIGIN('ArchiveURL') -- name of archive URL parameter for error messages Format = ArchiveFormat or ''; -- swap in archive's format UrlAccess = nil; -- restricted access levels do not make sense for archived URLs end end elseif utilities.is_set (UrlStatus) then -- if |url-status= is set when |archive-url= is not set utilities.set_message ('maint_url_status'); -- add maint cat end if utilities.in_array (config.CitationClass, {'web', 'news', 'journal', 'magazine', 'pressrelease', 'podcast', 'newsgroup', 'arxiv', 'biorxiv', 'citeseerx', 'medrxiv', 'ssrn'}) or -- if any of the 'periodical' cites except encyclopedia ('citation' == config.CitationClass and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) and not utilities.is_set (Encyclopedia)) then local chap_param; if utilities.is_set (Chapter) then -- get a parameter name from one of these chapter related meta-parameters chap_param = A:ORIGIN ('Chapter') elseif utilities.is_set (TransChapter) then chap_param = A:ORIGIN ('TransChapter') elseif utilities.is_set (ChapterURL) then chap_param = A:ORIGIN ('ChapterURL') elseif utilities.is_set (ScriptChapter) then chap_param = ScriptChapter_origin; else utilities.is_set (ChapterFormat) chap_param = A:ORIGIN ('ChapterFormat') end if utilities.is_set (chap_param) then -- if we found one utilities.set_message ('err_chapter_ignored', {chap_param}); -- add error message Chapter = ''; -- and set them to empty string to be safe with concatenation TransChapter = ''; ChapterURL = ''; ScriptChapter = ''; ChapterFormat = ''; end else -- otherwise, format chapter / article title local no_quotes = false; -- default assume that we will be quoting the chapter parameter value if utilities.is_set (Contribution) and 0 < #c then -- if this is a contribution with contributor(s) if utilities.in_array (Contribution:lower(), cfg.keywords_lists.contribution) then -- and a generic contribution title no_quotes = true; -- then render it unquoted end end Chapter = format_chapter_title (ScriptChapter, ScriptChapter_origin, Chapter, Chapter_origin, TransChapter, TransChapter_origin, ChapterURL, ChapterURL_origin, no_quotes, ChapterUrlAccess); -- Contribution is also in Chapter if utilities.is_set (Chapter) then Chapter = Chapter .. ChapterFormat ; if 'map' == config.CitationClass and utilities.is_set (TitleType) then Chapter = Chapter .. ' ' .. TitleType; -- map annotation here; not after title end Chapter = Chapter .. sepc .. ' '; elseif utilities.is_set (ChapterFormat) then -- |chapter= not set but |chapter-format= is so ... Chapter = ChapterFormat .. sepc .. ' '; -- ... ChapterFormat has error message, we want to see it end end -- Format main title local plain_title = false; local accept_title; Title, accept_title = utilities.has_accept_as_written (Title, true); -- remove accept-this-as-written markup when it wraps all of <Title> if accept_title and ('' == Title) then -- only support forced empty for now "(())" Title = cfg.messages['notitle']; -- replace by predefined "No title" message -- TODO: utilities.set_message ( 'err_redundant_parameters', ...); -- issue proper error message instead of muting ScriptTitle = ''; -- just mute for now TransTitle = ''; -- just mute for now plain_title = true; -- suppress text decoration for descriptive title utilities.set_message ('maint_untitled'); -- add maint cat end if not accept_title then -- <Title> not wrapped in accept-as-written markup if '...' == Title:sub (-3) then -- if ellipsis is the last three characters of |title= Title = Title:gsub ('(%.%.%.)%.+$', '%1'); -- limit the number of dots to three elseif not mw.ustring.find (Title, '%.%s*%a%.$') and -- end of title is not a 'dot-(optional space-)letter-dot' initialism ... not mw.ustring.find (Title, '%s+%a%.$') then -- ...and not a 'space-letter-dot' initial (''Allium canadense'' L.) Title = mw.ustring.gsub(Title, '%' .. sepc .. '$', ''); -- remove any trailing separator character; sepc and ms.ustring() here for languages that use multibyte separator characters end if utilities.is_set (ArchiveURL) and is_archived_copy (Title) then utilities.set_message ('maint_archived_copy'); -- add maintenance category before we modify the content of Title end if is_generic ('generic_titles', Title) then utilities.set_message ('err_generic_title'); -- set an error message end end if (not plain_title) and (utilities.in_array (config.CitationClass, {'web', 'news', 'journal', 'magazine', 'document', 'pressrelease', 'podcast', 'newsgroup', 'mailinglist', 'interview', 'arxiv', 'biorxiv', 'citeseerx', 'medrxiv', 'ssrn'}) or ('citation' == config.CitationClass and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) and not utilities.is_set (Encyclopedia)) or ('map' == config.CitationClass and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)))) then -- special case for cite map when the map is in a periodical treat as an article Title = kern_quotes (Title); -- if necessary, separate title's leading and trailing quote marks from module provided quote marks Title = utilities.wrap_style ('quoted-title', Title); Title = script_concatenate (Title, ScriptTitle, 'script-title'); -- <bdi> tags, lang attribute, categorization, etc.; must be done after title is wrapped TransTitle = utilities.wrap_style ('trans-quoted-title', TransTitle ); elseif plain_title or ('report' == config.CitationClass) then -- no styling for cite report and descriptive titles (otherwise same as above) Title = script_concatenate (Title, ScriptTitle, 'script-title'); -- <bdi> tags, lang attribute, categorization, etc.; must be done after title is wrapped TransTitle = utilities.wrap_style ('trans-quoted-title', TransTitle ); -- for cite report, use this form for trans-title else Title = utilities.wrap_style ('italic-title', Title); Title = script_concatenate (Title, ScriptTitle, 'script-title'); -- <bdi> tags, lang attribute, categorization, etc.; must be done after title is wrapped TransTitle = utilities.wrap_style ('trans-italic-title', TransTitle); end if utilities.is_set (TransTitle) then if utilities.is_set (Title) then TransTitle = " " .. TransTitle; else utilities.set_message ('err_trans_missing_title', {'title'}); end end if utilities.is_set (Title) then -- TODO: is this the right place to be making Wikisource URLs? if utilities.is_set (TitleLink) and utilities.is_set (URL) then utilities.set_message ('err_wikilink_in_url'); -- set an error message because we can't have both TitleLink = ''; -- unset end if not utilities.is_set (TitleLink) and utilities.is_set (URL) then Title = external_link (URL, Title, URL_origin, UrlAccess) .. TransTitle .. Format; URL = ''; -- unset these because no longer needed Format = ""; elseif utilities.is_set (TitleLink) and not utilities.is_set (URL) then local ws_url; ws_url = wikisource_url_make (TitleLink); -- ignore ws_label return; not used here if ws_url then Title = external_link (ws_url, Title .. '&nbsp;', 'ws link in title-link'); -- space char after Title to move icon away from italic text; TODO: a better way to do this? Title = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], TitleLink, Title}); Title = Title .. TransTitle; else Title = utilities.make_wikilink (TitleLink, Title) .. TransTitle; end else local ws_url, ws_label, L; -- Title has italic or quote markup by the time we get here which causes is_wikilink() to return 0 (not a wikilink) ws_url, ws_label, L = wikisource_url_make (Title:gsub('^[\'"]*(.-)[\'"]*$', '%1')); -- make ws URL from |title= interwiki link (strip italic or quote markup); link portion L becomes tooltip label if ws_url then Title = Title:gsub ('%b[]', ws_label); -- replace interwiki link with ws_label to retain markup Title = external_link (ws_url, Title .. '&nbsp;', 'ws link in title'); -- space char after Title to move icon away from italic text; TODO: a better way to do this? Title = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], L, Title}); Title = Title .. TransTitle; else Title = Title .. TransTitle; end end else Title = TransTitle; end if utilities.is_set (Place) then Place = " " .. wrap_msg ('written', Place, use_lowercase) .. sepc .. " "; end local ConferenceURL_origin = A:ORIGIN('ConferenceURL'); -- get name of parameter that holds ConferenceURL if utilities.is_set (Conference) then if utilities.is_set (ConferenceURL) then Conference = external_link( ConferenceURL, Conference, ConferenceURL_origin, nil ); end Conference = sepc .. " " .. Conference .. ConferenceFormat; elseif utilities.is_set (ConferenceURL) then Conference = sepc .. " " .. external_link( ConferenceURL, nil, ConferenceURL_origin, nil ); end local Position = ''; if not utilities.is_set (Position) then local Minutes = A['Minutes']; local Time = A['Time']; if utilities.is_set (Minutes) then if utilities.is_set (Time) then --TODO: make a function for this and similar? utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', 'minutes') .. cfg.presentation['sep_list_pair'] .. utilities.wrap_style ('parameter', 'time')}); end Position = " " .. Minutes .. " " .. cfg.messages['minutes']; else if utilities.is_set (Time) then local TimeCaption = A['TimeCaption'] if not utilities.is_set (TimeCaption) then TimeCaption = cfg.messages['event']; if sepc ~= '.' then TimeCaption = TimeCaption:lower(); end end Position = " " .. TimeCaption .. " " .. Time; end end else Position = " " .. Position; At = ''; end Page, Pages, Sheet, Sheets = format_pages_sheets (Page, Pages, Sheet, Sheets, config.CitationClass, Periodical_origin, sepc, NoPP, use_lowercase); At = utilities.is_set (At) and (sepc .. " " .. At) or ""; Position = utilities.is_set (Position) and (sepc .. " " .. Position) or ""; if config.CitationClass == 'map' then local Sections = A['Sections']; -- Section (singular) is an alias of Chapter so set earlier local Inset = A['Inset']; if utilities.is_set ( Inset ) then Inset = sepc .. " " .. wrap_msg ('inset', Inset, use_lowercase); end if utilities.is_set ( Sections ) then Section = sepc .. " " .. wrap_msg ('sections', Sections, use_lowercase); elseif utilities.is_set ( Section ) then Section = sepc .. " " .. wrap_msg ('section', Section, use_lowercase); end At = At .. Inset .. Section; end local Others = A['Others']; if utilities.is_set (Others) and 0 == #a and 0 == #e then -- add maint cat when |others= has value and used without |author=, |editor= if config.CitationClass == "AV-media-notes" or config.CitationClass == "audio-visual" then -- special maint for AV/M which has a lot of 'false' positives right now utilities.set_message ('maint_others_avm') else utilities.set_message ('maint_others'); end end Others = utilities.is_set (Others) and (sepc .. " " .. Others) or ""; if utilities.is_set (Translators) then Others = safe_join ({sepc .. ' ', wrap_msg ('translated', Translators, use_lowercase), Others}, sepc); end if utilities.is_set (Interviewers) then Others = safe_join ({sepc .. ' ', wrap_msg ('interview', Interviewers, use_lowercase), Others}, sepc); end local TitleNote = A['TitleNote']; TitleNote = utilities.is_set (TitleNote) and (sepc .. " " .. TitleNote) or ""; if utilities.is_set (Edition) then if Edition:match ('%f[%a][Ee]d%n?%.?$') or Edition:match ('%f[%a][Ee]dition$') then -- Ed, ed, Ed., ed., Edn, edn, Edn., edn. utilities.set_message ('err_extra_text_edition'); -- add error message end Edition = " " .. wrap_msg ('edition', Edition); else Edition = ''; end Series = utilities.is_set (Series) and wrap_msg ('series', {sepc, Series}) or ""; -- not the same as SeriesNum local Agency = A['Agency'] or ''; -- |agency= only supported in {{cite news}}, {{cite press release}}, {{cite web}} and certain {{citation}} templates if utilities.is_set (Agency) then -- this testing done here because {{citation}} supports 'news' citations if utilities.in_array (config.CitationClass, {'news', 'pressrelease', 'web'}) or ('citation' == config.CitationClass and utilities.in_array (Periodical_origin, {"newspaper", "work"})) then Agency = wrap_msg ('agency', {sepc, Agency}); -- format for rendering else Agency = ''; -- unset; not supported utilities.set_message ('err_parameter_ignored', {'agency'}); -- add error message end end Volume = format_volume_issue (Volume, Issue, ArticleNumber, config.CitationClass, Periodical_origin, sepc, use_lowercase); if utilities.is_set (AccessDate) then local retrv_text = " " .. cfg.messages['retrieved'] local status, result = pcall(formatDate, AccessDate) -- РУВИКИ: человекочитаемые даты if status then AccessDate = string.format("<span class='date'>%s</span>", result) else AccessDate = string.format("<span class='error'>(Строка «%s» не является верной датой, пожалуйста, укажите дату в формате <code>ГГГГ-ММ-ДД</code>)</span>", AccessDate) end -- AccessDate = nowrap_date (AccessDate); -- wrap in nowrap span if date in appropriate format if (sepc ~= ".") then retrv_text = retrv_text:lower() end -- if mode is cs2, lower case AccessDate = utilities.substitute (retrv_text, AccessDate); -- add retrieved text AccessDate = utilities.substitute (cfg.presentation['accessdate'], {sepc, AccessDate}); -- allow editors to hide accessdates end if utilities.is_set (ID) then ID = sepc .. " " .. ID; end local Docket = A['Docket']; if "thesis" == config.CitationClass and utilities.is_set (Docket) then ID = sepc .. " Docket " .. Docket .. ID; end if "report" == config.CitationClass and utilities.is_set (Docket) then -- for cite report when |docket= is set ID = sepc .. ' ' .. Docket; -- overwrite ID even if |id= is set end if utilities.is_set (URL) then URL = " " .. external_link( URL, nil, URL_origin, UrlAccess ); end local Quote = A['Quote']; local TransQuote = A['TransQuote']; local ScriptQuote = A['ScriptQuote']; if utilities.is_set (Quote) or utilities.is_set (TransQuote) or utilities.is_set (ScriptQuote) then if utilities.is_set (Quote) then if Quote:sub(1, 1) == '"' and Quote:sub(-1, -1) == '"' then -- if first and last characters of quote are quote marks Quote = Quote:sub(2, -2); -- strip them off end end Quote = kern_quotes (Quote); -- kern if needed Quote = utilities.wrap_style ('quoted-text', Quote ); -- wrap in <q>...</q> tags if utilities.is_set (ScriptQuote) then Quote = script_concatenate (Quote, ScriptQuote, 'script-quote'); -- <bdi> tags, lang attribute, categorization, etc.; must be done after quote is wrapped end if utilities.is_set (TransQuote) then if TransQuote:sub(1, 1) == '"' and TransQuote:sub(-1, -1) == '"' then -- if first and last characters of |trans-quote are quote marks TransQuote = TransQuote:sub(2, -2); -- strip them off end Quote = Quote .. " " .. utilities.wrap_style ('trans-quoted-title', TransQuote ); end if utilities.is_set (QuotePage) or utilities.is_set (QuotePages) then -- add page prefix local quote_prefix = ''; if utilities.is_set (QuotePage) then extra_text_in_page_check (QuotePage, 'quote-page'); -- add to maint cat if |quote-page= value begins with what looks like p., pp., etc. if not NoPP then quote_prefix = utilities.substitute (cfg.messages['p-prefix'], {sepc, QuotePage}), '', '', ''; else quote_prefix = utilities.substitute (cfg.messages['nopp'], {sepc, QuotePage}), '', '', ''; end elseif utilities.is_set (QuotePages) then extra_text_in_page_check (QuotePages, 'quote-pages'); -- add to maint cat if |quote-pages= value begins with what looks like p., pp., etc. if tonumber(QuotePages) ~= nil and not NoPP then -- if only digits, assume single page quote_prefix = utilities.substitute (cfg.messages['p-prefix'], {sepc, QuotePages}), '', ''; elseif not NoPP then quote_prefix = utilities.substitute (cfg.messages['pp-prefix'], {sepc, QuotePages}), '', ''; else quote_prefix = utilities.substitute (cfg.messages['nopp'], {sepc, QuotePages}), '', ''; end end Quote = quote_prefix .. ": " .. Quote; else Quote = sepc .. " " .. Quote; end PostScript = ""; -- cs1|2 does not supply terminal punctuation when |quote= is set end -- We check length of PostScript here because it will have been nuked by -- the quote parameters. We'd otherwise emit a message even if there wasn't -- a displayed postscript. -- TODO: Should the max size (1) be configurable? -- TODO: Should we check a specific pattern? if utilities.is_set(PostScript) and mw.ustring.len(PostScript) > 1 then utilities.set_message ('maint_postscript') end local Archived; if utilities.is_set (ArchiveURL) then if not utilities.is_set (ArchiveDate) then -- ArchiveURL set but ArchiveDate not set utilities.set_message ('err_archive_missing_date'); -- emit an error message ArchiveURL = ''; -- empty string for concatenation ArchiveDate = ''; -- empty string for concatenation end else if utilities.is_set (ArchiveDate) then -- ArchiveURL not set but ArchiveDate is set utilities.set_message ('err_archive_date_missing_url'); -- emit an error message ArchiveURL = ''; -- empty string for concatenation ArchiveDate = ''; -- empty string for concatenation end end if utilities.is_set (ArchiveURL) then local arch_text; local status, result = pcall(formatDate, ArchiveDate) -- РУВИКИ: человекочитаемые даты if status then ArchiveDate = string.format("<span class='date'>%s</span>", result) else ArchiveDate = string.format("<span class='error'>(Строка «%s» не является верной датой, пожалуйста, укажите дату в формате <code>ГГГГ-ММ-ДД</code>)</span>", ArchiveDate) end if "live" == UrlStatus or "" == UrlStatus then arch_text = cfg.messages['archived']; if sepc ~= "." then arch_text = arch_text:lower() end if utilities.is_set (ArchiveDate) then Archived = sepc .. ' ' .. utilities.substitute ( cfg.messages['archived-live'], {external_link( ArchiveURL, arch_text, A:ORIGIN('ArchiveURL'), nil) .. ArchiveFormat, ArchiveDate } ); else Archived = ''; end if not utilities.is_set (OriginalURL) then utilities.set_message ('err_archive_missing_url'); Archived = ''; -- empty string for concatenation end elseif utilities.is_set (OriginalURL) then -- UrlStatus is empty, 'dead', 'unfit', 'usurped', 'bot: unknown' if utilities.in_array (UrlStatus, {'unfit', 'usurped', 'bot: unknown'}) then arch_text = cfg.messages['archived-unfit']; if sepc ~= "." then arch_text = arch_text:lower() end Archived = sepc .. ' ' .. arch_text .. ArchiveDate; -- format already styled if 'bot: unknown' == UrlStatus then utilities.set_message ('maint_bot_unknown'); -- and add a category if not already added else utilities.set_message ('maint_unfit'); -- and add a category if not already added end else -- UrlStatus is empty, 'dead' arch_text = cfg.messages['archived-dead']; if sepc ~= "." then arch_text = arch_text:lower() end if utilities.is_set (ArchiveDate) then Archived = sepc .. " " .. utilities.substitute ( arch_text, { external_link( OriginalURL, cfg.messages['original'], OriginalURL_origin, OriginalAccess ) .. OriginalFormat, ArchiveDate } ); -- format already styled else Archived = ''; -- unset for concatenation end end else -- OriginalUrl not set utilities.set_message ('err_archive_missing_url'); Archived = ''; -- empty string for concatenation end elseif utilities.is_set (ArchiveFormat) then Archived = ArchiveFormat; -- if set and ArchiveURL not set ArchiveFormat has error message else Archived = ''; end local TranscriptURL = A['TranscriptURL'] local TranscriptFormat = A['TranscriptFormat']; TranscriptFormat = style_format (TranscriptFormat, TranscriptURL, 'transcript-format', 'transcripturl'); local Transcript = A['Transcript']; local TranscriptURL_origin = A:ORIGIN('TranscriptURL'); -- get name of parameter that holds TranscriptURL if utilities.is_set (Transcript) then if utilities.is_set (TranscriptURL) then Transcript = external_link( TranscriptURL, Transcript, TranscriptURL_origin, nil ); end Transcript = sepc .. ' ' .. Transcript .. TranscriptFormat; elseif utilities.is_set (TranscriptURL) then Transcript = external_link( TranscriptURL, nil, TranscriptURL_origin, nil ); end local Publisher; if utilities.is_set (PublicationDate) then PublicationDate = wrap_msg ('published', PublicationDate); end if utilities.is_set (PublisherName) then if utilities.is_set (PublicationPlace) then Publisher = sepc .. " " .. PublicationPlace .. ": " .. PublisherName .. PublicationDate; else Publisher = sepc .. " " .. PublisherName .. PublicationDate; end elseif utilities.is_set (PublicationPlace) then Publisher= sepc .. " " .. PublicationPlace .. PublicationDate; else Publisher = PublicationDate; end -- Several of the above rely upon detecting this as nil, so do it last. if (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical) or utilities.is_set (TransPeriodical)) then if utilities.is_set (Title) or utilities.is_set (TitleNote) then Periodical = sepc .. " " .. format_periodical (ScriptPeriodical, ScriptPeriodical_origin, Periodical, TransPeriodical, TransPeriodical_origin); else Periodical = format_periodical (ScriptPeriodical, ScriptPeriodical_origin, Periodical, TransPeriodical, TransPeriodical_origin); end end local Language = A['Language']; if utilities.is_set (Language) then Language = language_parameter (Language); -- format, categories, name from ISO639-1, etc. else Language=''; -- language not specified so make sure this is an empty string; --[[ TODO: need to extract the wrap_msg from language_parameter so that we can solve parentheses bunching problem with Format/Language/TitleType ]] end --[[ Handle the oddity that is cite speech. This code overrides whatever may be the value assigned to TitleNote (through |department=) and forces it to be " (Speech)" so that the annotation directly follows the |title= parameter value in the citation rather than the |event= parameter value (if provided). ]] if "speech" == config.CitationClass then -- cite speech only TitleNote = TitleType; -- move TitleType to TitleNote so that it renders ahead of |event= TitleType = ''; -- and unset if utilities.is_set (Periodical) then -- if Periodical, perhaps because of an included |website= or |journal= parameter if utilities.is_set (Conference) then -- and if |event= is set Conference = Conference .. sepc .. " "; -- then add appropriate punctuation to the end of the Conference variable before rendering end end end -- Piece all bits together at last. Here, all should be non-nil. -- We build things this way because it is more efficient in LUA -- not to keep reassigning to the same string variable over and over. local tcommon; local tcommon2; -- used for book cite when |contributor= is set if utilities.in_array (config.CitationClass, {"book", "citation"}) and not utilities.is_set (Periodical) then -- special cases for book cites if utilities.is_set (Contributors) then -- when we are citing foreword, preface, introduction, etc. tcommon = safe_join ({Title, TitleNote}, sepc); -- author and other stuff will come after this and before tcommon2 tcommon2 = safe_join ({TitleType, Series, Language, Volume, Others, Edition, Publisher}, sepc); else tcommon = safe_join ({Title, TitleNote, TitleType, Series, Language, Volume, Others, Edition, Publisher}, sepc); end elseif 'map' == config.CitationClass then -- special cases for cite map if utilities.is_set (Chapter) then -- map in a book; TitleType is part of Chapter tcommon = safe_join ({Title, Edition, Scale, Series, Language, Cartography, Others, Publisher, Volume}, sepc); elseif utilities.is_set (Periodical) then -- map in a periodical tcommon = safe_join ({Title, TitleType, Periodical, Scale, Series, Language, Cartography, Others, Publisher, Volume}, sepc); else -- a sheet or stand-alone map tcommon = safe_join ({Title, TitleType, Edition, Scale, Series, Language, Cartography, Others, Publisher}, sepc); end elseif 'episode' == config.CitationClass then -- special case for cite episode tcommon = safe_join ({Title, TitleNote, TitleType, Series, Language, Edition, Publisher}, sepc); else -- all other CS1 templates tcommon = safe_join ({Title, TitleNote, Conference, Periodical, TitleType, Series, Language, Volume, Others, Edition, Publisher, Agency}, sepc); end if #ID_list > 0 then ID_list = safe_join( { sepc .. " ", table.concat( ID_list, sepc .. " " ), ID }, sepc ); else ID_list = ID; end local Via = A['Via']; Via = utilities.is_set (Via) and wrap_msg ('via', Via) or ''; local idcommon; if 'audio-visual' == config.CitationClass or 'episode' == config.CitationClass then -- special case for cite AV media & cite episode position transcript idcommon = safe_join( { ID_list, URL, Archived, Transcript, AccessDate, Via, Quote }, sepc ); else idcommon = safe_join( { ID_list, URL, Archived, AccessDate, Via, Quote }, sepc ); end local text; local pgtext = Position .. Sheet .. Sheets .. Page .. Pages .. At; local OrigDate = A['OrigDate']; OrigDate = utilities.is_set (OrigDate) and wrap_msg ('origdate', OrigDate) or ''; if utilities.is_set (Date) then if utilities.is_set (Authors) or utilities.is_set (Editors) then -- date follows authors or editors when authors not set Date = " (" .. Date .. ")" .. OrigDate .. sepc .. " "; -- in parentheses else -- neither of authors and editors set if (string.sub(tcommon, -1, -1) == sepc) then -- if the last character of tcommon is sepc Date = " " .. Date .. OrigDate; -- Date does not begin with sepc else Date = sepc .. " " .. Date .. OrigDate; -- Date begins with sepc end end end if utilities.is_set (Authors) then if (not utilities.is_set (Date)) then -- when date is set it's in parentheses; no Authors termination Authors = terminate_name_list (Authors, sepc); -- when no date, terminate with 0 or 1 sepc and a space end if utilities.is_set (Editors) then local in_text = ''; local post_text = ''; if utilities.is_set (Chapter) and 0 == #c then in_text = cfg.messages['in'] .. ' '; if (sepc ~= '.') then in_text = in_text:lower(); -- lowercase for cs2 end end if EditorCount <= 1 then post_text = ' (' .. cfg.messages['editor'] .. ')'; -- be consistent with no-author, no-date case else post_text = ' (' .. cfg.messages['editors'] .. ')'; end Editors = terminate_name_list (in_text .. Editors .. post_text, sepc); -- terminate with 0 or 1 sepc and a space end if utilities.is_set (Contributors) then -- book cite and we're citing the intro, preface, etc. local by_text = sepc .. ' ' .. cfg.messages['by'] .. ' '; if (sepc ~= '.') then by_text = by_text:lower() end -- lowercase for cs2 Authors = by_text .. Authors; -- author follows title so tweak it here if utilities.is_set (Editors) and utilities.is_set (Date) then -- when Editors make sure that Authors gets terminated Authors = terminate_name_list (Authors, sepc); -- terminate with 0 or 1 sepc and a space end if (not utilities.is_set (Date)) then -- when date is set it's in parentheses; no Contributors termination Contributors = terminate_name_list (Contributors, sepc); -- terminate with 0 or 1 sepc and a space end text = safe_join( {Contributors, Date, Chapter, tcommon, Authors, Place, Editors, tcommon2, pgtext, idcommon }, sepc ); else text = safe_join( {Authors, Date, Chapter, Place, Editors, tcommon, pgtext, idcommon }, sepc ); end elseif utilities.is_set (Editors) then if utilities.is_set (Date) then if EditorCount <= 1 then Editors = Editors .. cfg.presentation['sep_name'] .. cfg.messages['editor']; else Editors = Editors .. cfg.presentation['sep_name'] .. cfg.messages['editors']; end else if EditorCount <= 1 then Editors = Editors .. " (" .. cfg.messages['editor'] .. ")" .. sepc .. " " else Editors = Editors .. " (" .. cfg.messages['editors'] .. ")" .. sepc .. " " end end text = safe_join( {Editors, Date, Chapter, Place, tcommon, pgtext, idcommon}, sepc ); else if utilities.in_array (config.CitationClass, {"journal", "citation"}) and utilities.is_set (Periodical) then text = safe_join( {Chapter, Place, tcommon, pgtext, Date, idcommon}, sepc ); else text = safe_join( {Chapter, Place, tcommon, Date, pgtext, idcommon}, sepc ); end end if utilities.is_set (PostScript) and PostScript ~= sepc then text = safe_join( {text, sepc}, sepc ); -- Deals with italics, spaces, etc. if '.' == sepc then -- remove final seperator if present text = text:gsub ('%' .. sepc .. '$', ''); -- dot must be escaped here else text = mw.ustring.gsub (text, sepc .. '$', ''); -- using ustring for non-dot sepc (likely a non-Latin character) end end text = safe_join( {text, PostScript}, sepc ); -- Now enclose the whole thing in a <cite> element local options_t = {}; options_t.class = cite_class_attribute_make (config.CitationClass, Mode); local Ref = is_valid_parameter_value (A['Ref'], A:ORIGIN('Ref'), cfg.keywords_lists['ref'], nil, true); -- nil when |ref=harv; A['Ref'] else -- Если указан параметр ref, то формируем ref-якорь по логике из рувики -- Если параметр не указан или ref=harv, то формируем якорь по енвики -- После зачистки всех ref=harv (~350), можно будет убрать код внутри utilities.is_set(Ref) if 'none' ~= cfg.keywords_xlate[(Ref and Ref:lower()) or ''] then local citeref_id = Ref local year = first_set ({Year, anchor_year}, 2); -- Year first for legacy citations and for YMD dates that require disambiguation if not utilities.is_set(Ref) then local namelist_t = {}; -- holds selected contributor, author, editor name list if #c > 0 then -- if there is a contributor list namelist_t = c; -- select it elseif #a > 0 then -- or an author list namelist_t = a; elseif #e > 0 then -- or an editor list namelist_t = e; end if #namelist_t > 0 then -- if there are names in namelist_t citeref_id = make_citeref_id (namelist_t, year); -- go make the CITEREF anchor if mw.uri.anchorEncode (citeref_id) == ((Ref and mw.uri.anchorEncode (Ref)) or '') then -- Ref may already be encoded (by {{sfnref}}) so citeref_id must be encoded before comparison utilities.set_message ('maint_ref_duplicates_default'); end else citeref_id = ''; -- unset end elseif mw.ustring.sub(Ref, 0, 7) ~= 'CITEREF' then -- для рувики: иная генерация ref-якорей if mw.ustring.match(citeref_id, '%d%d%d%d') then citeref_id = 'CITEREF' .. citeref_id else local yearForRef = nil if year and mw.ustring.match(year, '^%d%d%d%d$') then yearForRef = mw.ustring.match(year, '^%d%d%d%d$') elseif Date and mw.ustring.match(Date, '%d%d%d%d') then yearForRef = mw.ustring.match(Date, '%d%d%d%d') end if yearForRef then citeref_id = 'CITEREF' .. citeref_id .. yearForRef else citeref_id = '' -- TODO: для рувики: выдавать ошибку? end end end options_t.id = citeref_id or ''; end if string.len (text:gsub('%b<>', '')) <= 2 then -- remove html and html-like tags; then get length of what remains; z.error_cats_t = {}; -- blank the categories list z.error_msgs_t = {}; -- blank the error messages list OCinSoutput = nil; -- blank the metadata string text = ''; -- blank the the citation utilities.set_message ('err_empty_citation'); -- set empty citation message and category end local render_t = {}; -- here we collect the final bits for concatenation into the rendered citation if utilities.is_set (options_t.id) then -- here we wrap the rendered citation in <cite ...>...</cite> tags table.insert (render_t, utilities.substitute (cfg.presentation['cite-id'], {mw.uri.anchorEncode(options_t.id), mw.text.nowiki(options_t.class), text})); -- when |ref= is set or when there is a namelist else table.insert (render_t, utilities.substitute (cfg.presentation['cite'], {mw.text.nowiki(options_t.class), text})); -- when |ref=none or when namelist_t empty and |ref= is missing or is empty end if OCinSoutput then -- blanked when citation is 'empty' so don't bother to add boilerplate metadata span table.insert (render_t, utilities.substitute (cfg.presentation['ocins'], OCinSoutput)); -- format and append metadata to the citation end local template_name = ('citation' == config.CitationClass) and 'citation' or 'cite ' .. (cfg.citation_class_map_t[config.CitationClass] or config.CitationClass); local template_link = '[[Template:' .. template_name .. '|' .. template_name .. ']]'; local msg_prefix = '<code class="cs1-code">{{' .. template_link .. '}}</code>: '; if 0 ~= #z.error_msgs_t then mw.addWarning (utilities.substitute (cfg.messages.warning_msg_e, template_link)); table.insert (render_t, ' '); -- insert a space between citation and its error messages table.sort (z.error_msgs_t); -- sort the error messages list; sorting includes wrapping <span> and <code> tags; hidden-error sorts ahead of visible-error local hidden = true; -- presume that the only error messages emited by this template are hidden for _, v in ipairs (z.error_msgs_t) do -- spin through the list of error messages if v:find ('cs1-visible-error', 1, true) then -- look for the visible error class name hidden = false; -- found one; so don't hide the error message prefix break; -- and done because no need to look further end end z.error_msgs_t[1] = table.concat ({utilities.error_comment (msg_prefix, hidden), z.error_msgs_t[1]}); -- add error message prefix to first error message to prevent extraneous punctuation table.insert (render_t, table.concat (z.error_msgs_t, '; ')); -- make a big string of error messages and add it to the rendering end if 0 ~= #z.maint_cats_t then mw.addWarning (utilities.substitute (cfg.messages.warning_msg_m, template_link)); table.sort (z.maint_cats_t); -- sort the maintenance messages list local maint_msgs_t = {}; -- here we collect all of the maint messages if 0 == #z.error_msgs_t then -- if no error messages table.insert (maint_msgs_t, msg_prefix); -- insert message prefix in maint message livery end for _, v in ipairs( z.maint_cats_t ) do -- append maintenance categories table.insert (maint_msgs_t, -- assemble new maint message and add it to the maint_msgs_t table table.concat ({v, ' (', utilities.substitute (cfg.messages[':cat wikilink'], v), ')'}) ); end table.insert (render_t, utilities.substitute (cfg.presentation['hidden-maint'], table.concat (maint_msgs_t, ' '))); -- wrap the group of maint messages with proper presentation and save end if not no_tracking_cats then local sort_key; local cat_wikilink = 'cat wikilink'; if cfg.enable_sort_keys then -- when namespace sort keys enabled local namespace_number = mw.title.getCurrentTitle().namespace; -- get namespace number for this wikitext sort_key = (0 ~= namespace_number and (cfg.name_space_sort_keys[namespace_number] or cfg.name_space_sort_keys.other)) or nil; -- get sort key character; nil for mainspace cat_wikilink = (not sort_key and 'cat wikilink') or 'cat wikilink sk'; -- make <cfg.messages> key end for _, v in ipairs (z.error_cats_t) do -- append error categories table.insert (render_t, utilities.substitute (cfg.messages[cat_wikilink], {v, sort_key})); end for _, v in ipairs (z.maint_cats_t) do -- append maintenance categories table.insert (render_t, utilities.substitute (cfg.messages[cat_wikilink], {v, sort_key})); end -- for _, v in ipairs (z.prop_cats_t) do -- append properties categories -- table.insert (render_t, utilities.substitute (cfg.messages['cat wikilink'], v)); -- no sort keys -- end end return table.concat (render_t); -- make a big string and done end --[[--------------------------< V A L I D A T E >-------------------------------------------------------------- Looks for a parameter's name in one of several whitelists. Parameters in the whitelist can have three values: true - active, supported parameters false - deprecated, supported parameters nil - unsupported parameters ]] local function validate (name, cite_class, empty) local name = tostring (name); local enum_name; -- parameter name with enumerator (if any) replaced with '#' local state; local function state_test (state, name) -- local function to do testing of state values if true == state then return true; end -- valid actively supported parameter if false == state then if empty then return nil; end -- empty deprecated parameters are treated as unknowns deprecated_parameter (name); -- parameter is deprecated but still supported return true; end if 'tracked' == state then local base_name = name:gsub ('%d', ''); -- strip enumerators from parameter names that have them to get the base name utilities.add_prop_cat ('tracked-param', {base_name}, base_name); -- add a properties category; <base_name> modifies <key> return true; end return nil; end if name:find ('#') then -- # is a cs1|2 reserved character so parameters with # not permitted return nil; end -- replace enumerator digit(s) with # (|last25= becomes |last#=) (mw.ustring because non-Western 'local' digits) enum_name = mw.ustring.gsub (name, '%d+$', '#'); -- where enumerator is last charaters in parameter name (these to protect |s2cid=) enum_name = mw.ustring.gsub (enum_name, '%d+([%-l])', '#%1'); -- where enumerator is in the middle of the parameter name; |author#link= is the oddity if 'document' == cite_class then -- special case for {{cite document}} state = whitelist.document_parameters_t[enum_name]; -- this list holds enumerated and nonenumerated parameters if true == state_test (state, name) then return true; end return false; end if utilities.in_array (cite_class, whitelist.preprint_template_list_t) then -- limited parameter sets allowed for these templates state = whitelist.limited_parameters_t[enum_name]; -- this list holds enumerated and nonenumerated parameters if true == state_test (state, name) then return true; end state = whitelist.preprint_arguments_t[cite_class][name]; -- look in the parameter-list for the template identified by cite_class if true == state_test (state, name) then return true; end return false; -- not supported because not found or name is set to nil end -- end limited parameter-set templates if utilities.in_array (cite_class, whitelist.unique_param_template_list_t) then -- template-specific parameters for templates that accept parameters from the basic argument list state = whitelist.unique_arguments_t[cite_class][name]; -- look in the template-specific parameter-lists for the template identified by cite_class if true == state_test (state, name) then return true; end end -- if here, fall into general validation state = whitelist.common_parameters_t[enum_name]; -- all other templates; all normal parameters allowed; this list holds enumerated and nonenumerated parameters if true == state_test (state, name) then return true; end return false; -- not supported because not found or name is set to nil end --[=[-------------------------< I N T E R _ W I K I _ C H E C K >---------------------------------------------- check <value> for inter-language interwiki-link markup. <prefix> must be a MediaWiki-recognized language code. when these values have the form (without leading colon): [[<prefix>:link|label]] return label as plain-text [[<prefix>:link]] return <prefix>:link as plain-text return value as is else ]=] local function inter_wiki_check (parameter, value) local prefix = value:match ('%[%[(%a+):'); -- get an interwiki prefix if one exists local _; if prefix and cfg.inter_wiki_map[prefix:lower()] then -- if prefix is in the map, needs preceding colon so utilities.set_message ('err_bad_paramlink', parameter); -- emit an error message _, value, _ = utilities.is_wikilink (value); -- extract label portion from wikilink end return value; end --[[--------------------------< M I S S I N G _ P I P E _ C H E C K >------------------------------------------ Look at the contents of a parameter. If the content has a string of characters and digits followed by an equal sign, compare the alphanumeric string to the list of cs1|2 parameters. If found, then the string is possibly a parameter that is missing its pipe. There are two tests made: {{cite ... |title=Title access-date=2016-03-17}} -- the first parameter has a value and whitespace separates that value from the missing pipe parameter name {{cite ... |title=access-date=2016-03-17}} -- the first parameter has no value (whitespace after the first = is trimmed by MediaWiki) cs1|2 shares some parameter names with XML/HTML attributes: class=, title=, etc. To prevent false positives XML/HTML tags are removed before the search. If a missing pipe is detected, this function adds the missing pipe maintenance category. ]] local function missing_pipe_check (parameter, value) local capture; value = value:gsub ('%b<>', ''); -- remove XML/HTML tags because attributes: class=, title=, etc. capture = value:match ('%s+(%a[%w%-]+)%s*=') or value:match ('^(%a[%w%-]+)%s*='); -- find and categorize parameters with possible missing pipes if capture and validate (capture) then -- if the capture is a valid parameter name utilities.set_message ('err_missing_pipe', parameter); end end --[[--------------------------< H A S _ E X T R A N E O U S _ P U N C T >-------------------------------------- look for extraneous terminal punctuation in most parameter values; parameters listed in skip table are not checked ]] local function has_extraneous_punc (param, value) if 'number' == type (param) then return; end param = param:gsub ('%d+', '#'); -- enumerated name-list mask params allow terminal punct; normalize if cfg.punct_skip[param] then return; -- parameter name found in the skip table so done end if value:match ('[,;:]$') then utilities.set_message ('maint_extra_punct'); -- has extraneous punctuation; add maint cat end if value:match ('^=') then -- sometimes an extraneous '=' character appears ... utilities.set_message ('maint_extra_punct'); -- has extraneous punctuation; add maint cat end end --[[--------------------------< H A S _ E X T R A N E O U S _ U R L >------------------------------------------ look for extraneous url parameter values; parameters listed in skip table are not checked ]] local function has_extraneous_url (url_param_t) local url_error_t = {}; check_for_url (url_param_t, url_error_t); -- extraneous url check if 0 ~= #url_error_t then -- non-zero when there are errors table.sort (url_error_t); utilities.set_message ('err_param_has_ext_link', {utilities.make_sep_list (#url_error_t, url_error_t)}); -- add this error message end end --[[--------------------------< C I T A T I O N >-------------------------------------------------------------- This is used by templates such as {{cite book}} to create the actual citation text. ]] local function citation(frame) Frame = frame; -- save a copy in case we need to display an error message in preview mode local config = {}; -- table to store parameters from the module {{#invoke:}} for k, v in pairs( frame.args ) do -- get parameters from the {{#invoke}} frame config[k] = v; -- args[k] = v; -- crude debug support that allows us to render a citation from module {{#invoke:}}; skips parameter validation; TODO: keep? end -- i18n: set the name that your wiki uses to identify sandbox subpages from sandbox template invoke (or can be set here) local sandbox = ((config.SandboxPath and '' ~= config.SandboxPath) and config.SandboxPath) or '/sandbox'; -- sandbox path from {{#invoke:Citation/CS1/sandbox|citation|SandboxPath=/...}} is_sandbox = nil ~= string.find (frame:getTitle(), sandbox, 1, true); -- is this invoke the sandbox module? sandbox = is_sandbox and sandbox or ''; -- use i18n sandbox to load sandbox modules when this module is the sandox; live modules else local pframe = frame:getParent() local styles; cfg = mw.loadData ('Module:Citation/CS1/Configuration' .. sandbox); -- load sandbox versions of support modules when {{#invoke:Citation/CS1/sandbox|...}}; live modules else whitelist = mw.loadData ('Module:Citation/CS1/Whitelist' .. sandbox); utilities = require ('Module:Citation/CS1/Utilities' .. sandbox); validation = require ('Module:Citation/CS1/Date_validation' .. sandbox); identifiers = require ('Module:Citation/CS1/Identifiers' .. sandbox); metadata = require ('Module:Citation/CS1/COinS' .. sandbox); styles = 'Module:Citation/CS1' .. sandbox .. '/styles.css'; utilities.set_selected_modules (cfg); -- so that functions in Utilities can see the selected cfg tables identifiers.set_selected_modules (cfg, utilities); -- so that functions in Identifiers can see the selected cfg tables and selected Utilities module validation.set_selected_modules (cfg, utilities); -- so that functions in Date validataion can see selected cfg tables and the selected Utilities module metadata.set_selected_modules (cfg, utilities); -- so that functions in COinS can see the selected cfg tables and selected Utilities module z = utilities.z; -- table of error and category tables in Module:Citation/CS1/Utilities is_preview_mode = not utilities.is_set (frame:preprocess ('{{REVISIONID}}')); local args = {}; -- table where we store all of the template's arguments local suggestions = {}; -- table where we store suggestions if we need to loadData them local error_text; -- used as a flag local capture; -- the single supported capture when matching unknown parameters using patterns local empty_unknowns = {}; -- sequence table to hold empty unknown params for error message listing for k, v in pairs( pframe.args ) do -- get parameters from the parent (template) frame v = mw.ustring.gsub (v, '^%s*(.-)%s*$', '%1'); -- trim leading/trailing whitespace; when v is only whitespace, becomes empty string if v ~= '' then if ('string' == type (k)) then k = mw.ustring.gsub (k, '%d', cfg.date_names.local_digits); -- for enumerated parameters, translate 'local' digits to Western 0-9 end if not validate( k, config.CitationClass ) then if type (k) ~= 'string' then -- exclude empty numbered parameters if v:match("%S+") ~= nil then error_text = utilities.set_message ('err_text_ignored', {v}); end elseif validate (k:lower(), config.CitationClass) then error_text = utilities.set_message ('err_parameter_ignored_suggest', {k, k:lower()}); -- suggest the lowercase version of the parameter else if nil == suggestions.suggestions then -- if this table is nil then we need to load it suggestions = mw.loadData ('Module:Citation/CS1/Suggestions' .. sandbox); --load sandbox version of suggestion module when {{#invoke:Citation/CS1/sandbox|...}}; live module else end for pattern, param in pairs (suggestions.patterns) do -- loop through the patterns to see if we can suggest a proper parameter capture = k:match (pattern); -- the whole match if no capture in pattern else the capture if a match if capture then -- if the pattern matches param = utilities.substitute (param, capture); -- add the capture to the suggested parameter (typically the enumerator) if validate (param, config.CitationClass) then -- validate the suggestion to make sure that the suggestion is supported by this template (necessary for limited parameter lists) error_text = utilities.set_message ('err_parameter_ignored_suggest', {k, param}); -- set the suggestion error message else error_text = utilities.set_message ('err_parameter_ignored', {k}); -- suggested param not supported by this template v = ''; -- unset end end end if not utilities.is_set (error_text) then -- couldn't match with a pattern, is there an explicit suggestion? if (suggestions.suggestions[ k:lower() ] ~= nil) and validate (suggestions.suggestions[ k:lower() ], config.CitationClass) then utilities.set_message ('err_parameter_ignored_suggest', {k, suggestions.suggestions[ k:lower() ]}); else utilities.set_message ('err_parameter_ignored', {k}); v = ''; -- unset value assigned to unrecognized parameters (this for the limited parameter lists) end end end end args[k] = v; -- save this parameter and its value elseif not utilities.is_set (v) then -- for empty parameters if not validate (k, config.CitationClass, true) then -- is this empty parameter a valid parameter k = ('' == k) and '(empty string)' or k; -- when k is empty string (or was space(s) trimmed to empty string), replace with descriptive text table.insert (empty_unknowns, utilities.wrap_style ('parameter', k)); -- format for error message and add to the list end -- crude debug support that allows us to render a citation from module {{#invoke:}} TODO: keep? -- elseif args[k] ~= nil or (k == 'postscript') then -- when args[k] has a value from {{#invoke}} frame (we don't normally do that) -- args[k] = v; -- overwrite args[k] with empty string from pframe.args[k] (template frame); v is empty string here end -- not sure about the postscript bit; that gets handled in parameter validation; historical artifact? end if 0 ~= #empty_unknowns then -- create empty unknown error message utilities.set_message ('err_param_unknown_empty', { 1 == #empty_unknowns and '' or 's', utilities.make_sep_list (#empty_unknowns, empty_unknowns) }); end local url_param_t = {}; for k, v in pairs( args ) do if 'string' == type (k) then -- don't evaluate positional parameters has_invisible_chars (k, v); -- look for invisible characters end has_extraneous_punc (k, v); -- look for extraneous terminal punctuation in parameter values missing_pipe_check (k, v); -- do we think that there is a parameter that is missing a pipe? args[k] = inter_wiki_check (k, v); -- when language interwiki-linked parameter missing leading colon replace with wiki-link label if 'string' == type (k) and not cfg.url_skip[k] then -- when parameter k is not positional and not in url skip table url_param_t[k] = v; -- make a parameter/value list for extraneous url check end end has_extraneous_url (url_param_t); -- look for url in parameter values where a url does not belong return table.concat ({ frame:extensionTag ('templatestyles', '', {src=styles}), citation0( config, args) }); end --[[--------------------------< E X P O R T E D F U N C T I O N S >------------------------------------------ ]] return {citation = citation}; 79118ee25d3a893b095e8a280156cc50dc140901 Модуль:Hatnote 828 79 131 130 2024-08-09T16:56:43Z DuOfOrl 5 1 версия импортирована Scribunto text/plain local get_args = require('Module:Arguments').getArgs local mError local yesno = function (v) return require('Module:Yesno')(v, true) end local p, tr = {}, {} local current_title = mw.title.getCurrentTitle() local tracking_categories = { no_prefix = 'Википедия:Страницы с модулем Hatnote без указания префикса', no_links = 'Википедия:Страницы с модулем Hatnote без ссылок', red_link = 'Википедия:Страницы с модулем Hatnote с красной ссылкой', bad_format = 'Википедия:Страницы с модулем Hatnote с некорректно заполненными параметрами', unparsable_link = 'Википедия:Страницы с модулем Hatnote с нечитаемой ссылкой', formatted = 'Википедия:Страницы с модулем Hatnote с готовым форматированием', } local function index(t1, t2) return setmetatable(t1, {__index = t2}) end local function concat(e1, e2) return tostring(e1) .. tostring(e2) end function tr.define_categories(tracked_cases) local categories = setmetatable({}, { __tostring = function (self) return table.concat(self) end, __concat = concat }) function categories:add(element, nocat) if not nocat then local cat_name if tracked_cases and tracked_cases[element] then cat_name = tracked_cases[element] else cat_name = element end table.insert(self, string.format('[[Категория:%s]]', cat_name)) end end return categories end function tr.error(msg, categories, preview_only) local current_frame = mw.getCurrentFrame() local parent_frame = current_frame:getParent() local res_frame_title = parent_frame and parent_frame:getTitle() ~= current_title.prefixedText and parent_frame:getTitle() or current_frame:getTitle() if not preview_only or current_frame:preprocess('{{REVISIONID}}') == '' then mError = require('Module:Error') return mError.error{ tag = 'div', string.format('Ошибка в [[%s]]: %s.' .. (preview_only and '<br><small>Это сообщение показывается только во время предпросмотра.</small>' or ''), res_frame_title, msg) } .. categories else return categories end end function p.parse_link(frame) local args = get_args(frame) local link = args[1]:gsub('\n', '') local label link = mw.text.trim(link:match('^%[%[([^%]]+)%]%]$') or link) if link:sub(1, 1) == '/' then label = link link = current_title.prefixedText .. link end link = link:match(':?(.+)') if link:match('|') then link, label = link:match('^([^%|]+)%|(.+)$') end if not mw.title.new(link) then return nil, nil end return link, label end function p.format_link(frame) -- {{ссылка на раздел}} local args = get_args(frame) local link, section, label = args[1], args[2], args[3] if not link then link = current_title.prefixedText if section then link = '#' .. section label = label or '§&nbsp;' .. section end else local parsed_link, parsed_label = p.parse_link{link} if parsed_link then link = parsed_link else return link end if section and not link:match('#') then link = link .. '#' .. section if parsed_label then parsed_label = parsed_label .. '#' .. section end end label = (label or parsed_label or link):gsub('^([^#]-)#(.+)$', '%1 §&nbsp;%2') end if label and label ~= link then return string.format('[[:%s|%s]]', link, label) else return string.format('[[:%s]]', link) end end function p.remove_precision(frame) -- {{без уточнения}} local args = get_args(frame) local title = args[1] return title:match('^(.+)%s+%b()$') or title end function p.is_disambig(frame) local args = get_args(frame) local title = args[1] local page = mw.title.new(title) if not page or not page.exists or mw.title.equals(page, current_title) then return false end local page_content = page:getContent() local mw_list_content = mw.title.new('MediaWiki:Disambiguationspage'):getContent() local lang = mw.language.getContentLanguage() for template in mw.ustring.gmatch(mw_list_content, '%*%s?%[%[Шаблон:([^%]]+)') do if page_content:match('{{' .. template) or page_content:match('{{' .. lang:lcfirst(template)) then return true end end return false end function p.list(frame) local args = get_args(frame, {trim = false}) local list_sep = args.list_sep or args['разделитель списка'] or ', ' local last_list_sep = yesno(args.natural_join) ~= false and ' и ' or list_sep local links_ns = args.links_ns or args['ПИ ссылок'] local bold_links = yesno(args.bold_links or args['ссылки болдом']) local res_list = {} local tracked = { red_link = false, bad_format = false, formatted = false, unparsable_link = false } local i = 1 while args[i] do local link = args[i] local label = args['l' .. i] local element = '' if link:match('<span') then -- TODO: переписать tracked.formatted = true element = link -- for {{не переведено}} else local bad_format = (link:match('|') or link:match('[%[%]]')) ~= nil local parsed_link, parsed_label = p.parse_link{link} if parsed_link then tracked.bad_format = tracked.bad_format or bad_format if links_ns then parsed_label = parsed_label or parsed_link parsed_link = mw.site.namespaces[links_ns].name .. ':' .. parsed_link end local title = mw.title.new(parsed_link) tracked.red_link = tracked.red_link or not (title.isExternal or title.exists) element = p.format_link{parsed_link, nil, label or parsed_label} else tracked.unparsable_link = true element = link end end if bold_links then element = string.format('<b>%s</b>', element) end table.insert(res_list, element) i = i + 1 end return setmetatable(res_list, { __index = tracked, __tostring = function (self) return mw.text.listToText(self, list_sep, last_list_sep) end, __concat = concat, __pairs = function (self) return pairs(tracked) end }) end function p.hatnote(frame) local args = get_args(frame) local text = args[1] local id = args.id local extraclasses = args.extraclasses local hide_disambig = yesno(args.hide_disambig) local res = mw.html.create('div') :attr('id', id) :addClass('hatnote') :addClass('navigation-not-searchable') :addClass(extraclasses) :wikitext(text) if hide_disambig then res:addClass('dabhide') end return res end function p.main(frame, _tracking_categories) local args = get_args(frame, {trim = false}) local prefix = args.prefix or args['префикс'] local prefix_plural = args.prefix_plural or args['префикс мн. ч.'] local sep = args.sep or args['разделитель'] or ' ' local dot = yesno(args.dot or args['точка']) and '.' or '' local nocat = yesno(args.nocat) local preview_error = yesno(args.preview_error) local empty_list_message = args.empty_list_message or 'Не указано ни одной страницы' categories = tr.define_categories(index(_tracking_categories or {}, tracking_categories)) if not prefix then categories:add('no_prefix', nocat) return tr.error('Не указан префикс', categories) end if not args[1] then categories:add('no_links', nocat) return tr.error(empty_list_message, categories, preview_error) end if args[2] and prefix_plural then prefix = prefix_plural end local list = p.list(args) for k, v in pairs(list) do if type(v) == 'boolean' and v then categories:add(k, nocat) end end return p.hatnote(index({prefix .. sep .. list .. dot}, args)) .. categories end return index(p, tr) 315cdda5f53c2b0188793a6cc6c40f7f371361e0 Модуль:Unsubst 828 80 133 132 2024-08-09T16:58:24Z DuOfOrl 5 1 версия импортирована Scribunto text/plain local checkType = require('libraryUtil').checkType local p = {} local BODY_PARAM = '$B' local specialParams = { ['$params'] = 'parameter list', ['$aliases'] = 'parameter aliases', ['$flags'] = 'flags', ['$format'] = 'date format', ['$B'] = 'template content' } function p.main(frame, body) -- If we are substing, this function returns a template invocation, and if -- not, it returns the template body. The template body can be specified in -- the body parameter, or in the template parameter defined in the -- BODY_PARAM variable. This function can be called from Lua or from -- #invoke. -- Return the template body if we aren't substing. if not mw.isSubsting() then if body ~= nil then return body elseif frame.args[BODY_PARAM] ~= nil then return frame.args[BODY_PARAM] else error(string.format( "no template content specified (use parameter '%s' from #invoke)", BODY_PARAM ), 2) end end -- Sanity check for the frame object. if type(frame) ~= 'table' or type(frame.getParent) ~= 'function' or not frame:getParent() then error( "argument #1 to 'main' must be a frame object with a parent " .. "frame available", 2 ) end -- Find the invocation name. local mTemplateInvocation = require('Module:Template invocation') local name = mTemplateInvocation.name(frame:getParent():getTitle()) -- Combine passed args with passed defaults local args = {} local format = frame.args['$format'] or 'j xg Y' if string.find( ','..(frame.args['$flags'] or '')..',', ',%s*override%s*,' ) then for k, v in pairs( frame:getParent().args ) do args[k] = v end for k, v in pairs( frame.args ) do if not specialParams[k] then if v == '__DATE__' then v = mw.getContentLanguage():formatDate( format ) end args[k] = v end end else for k, v in pairs( frame.args ) do if not specialParams[k] then if v == '__DATE__' then v = mw.getContentLanguage():formatDate( format ) end args[k] = v end end for k, v in pairs( frame:getParent().args ) do args[k] = v end end -- Trim parameters, if not specified otherwise if not string.find( ','..(frame.args['$flags'] or '')..',', ',%s*keep%-whitespace%s*,' ) then for k, v in pairs( args ) do args[k] = mw.ustring.match(v, '^%s*(.*)%s*$') or '' end end -- Pull information from parameter aliases local aliases = {} if frame.args['$aliases'] then local list = mw.text.split( frame.args['$aliases'], '%s*,%s*' ) for k, v in ipairs( list ) do local tmp = mw.text.split( v, '%s*>%s*' ) aliases[tonumber(mw.ustring.match(tmp[1], '^[1-9][0-9]*$')) or tmp[1]] = ((tonumber(mw.ustring.match(tmp[2], '^[1-9][0-9]*$'))) or tmp[2]) end end for k, v in pairs( aliases ) do if args[k] and ( not args[v] or args[v] == '' ) then args[v] = args[k] end args[k] = nil end -- Remove empty parameters, if specified if string.find( ','..(frame.args['$flags'] or '')..',', ',%s*remove%-empty%s*,' ) then local tmp = 0 for k, v in ipairs( args ) do if v ~= '' or ( args[k+1] and args[k+1] ~= '' ) or ( args[k+2] and args[k+2] ~= '' ) then tmp = k else break end end for k, v in pairs( args ) do if v == '' then if not (type(k) == 'number' and k < tmp) then args[k] = nil end end end end -- Order parameters if frame.args['$params'] then local params, tmp = mw.text.split( frame.args['$params'], '%s*,%s*' ), {} for k, v in ipairs(params) do v = tonumber(mw.ustring.match(v, '^[1-9][0-9]*$')) or v if args[v] then tmp[v], args[v] = args[v], nil end end for k, v in pairs(args) do tmp[k], args[k] = args[k], nil end args = tmp end return mTemplateInvocation.invocation(name, args) end p[''] = p.main -- For backwards compatibility return p 66516cd1b82c9c1f13ac5cc5b9a87e1c93242068 Модуль:Sidebar 828 81 135 134 2024-08-09T17:00:12Z DuOfOrl 5 1 версия импортирована Scribunto text/plain -- -- Этот модуль обеспечивает работу шаблона {{Sidebar}} -- require('strict') local p = {} local getArgs = require('Модуль:Arguments').getArgs local navbar = require('Модуль:Navbar')._navbar local function trimAndAddAutomaticNewline(s) -- For compatibility with the original {{sidebar with collapsible lists}} -- implementation, which passed some parameters through {{#if}} to trim -- their whitespace. This also triggered the automatic newline behavior. -- ([[meta:Help:Newlines and spaces#Automatic newline]]) s = mw.ustring.gsub(s, "^%s*(.-)%s*$", "%1") if mw.ustring.find(s, '^[#*:;]') or mw.ustring.find(s, '^{|') then return '\n' .. s else return s end end function p.sidebar(frame, args) if not args then args = getArgs(frame) end local root = mw.html.create() local child = args.child and mw.text.trim(args.child) == 'yes' if not child then root = root :tag('table') :addClass('vertical-navbox') :addClass(args.wraplinks ~= 'true' and 'nowraplinks' or nil) :addClass(args.bodyclass or args.class) :css('float', args.float or 'right') :css('clear', (args.float == 'none' and 'both') or args.float or 'right') :css('width', args.width or '22.0em') :css('margin', args.float == 'left' and '0 1.0em 1.0em 0' or '0 0 1.0em 1.0em') :css('background', '#f9f9f9') :css('border', '1px solid #aaa') :css('padding', '0.2em') :css('border-spacing', '0.4em 0') :css('text-align', 'center') :css('line-height', '1.4em') :css('font-size', '88%') :cssText(args.bodystyle or args.style) if args.outertitle then root :tag('caption') :addClass(args.outertitleclass) :css('padding-bottom', '0.2em') :css('font-size', '125%') :css('line-height', '1.2em') :css('font-weight', 'bold') :cssText(args.outertitlestyle) :wikitext(args.outertitle) end if args.topimage then local imageCell = root:tag('tr'):tag('td') imageCell :addClass(args.topimageclass) :css('padding', '0.4em 0') :cssText(args.topimagestyle) :wikitext(args.topimage) if args.topcaption then imageCell :tag('div') :css('padding-top', '0.2em') :css('line-height', '1.2em') :cssText(args.topcaptionstyle) :wikitext(args.topcaption) end end if args.pretitle then root :tag('tr') :tag('td') :addClass(args.pretitleclass) :cssText(args.basestyle) :css('padding-top', args.topimage and '0.2em' or '0.4em') :css('line-height', '1.2em') :cssText(args.pretitlestyle) :wikitext(args.pretitle) end end if args.title then if child then root :wikitext(args.title) :wikitext('</th></tr>') -- @todo replace this with unclosed again once mw.html gets it else root :tag('tr') :tag('th') :addClass(args.titleclass) :cssText(args.basestyle) :css('padding', '0.2em 0.4em 0.2em') :css('padding-top', args.pretitle and 0) :css('font-size', '145%') :css('line-height', '1.2em') :cssText(args.titlestyle) :wikitext(args.title) end end if args.image then local imageCell = root:tag('tr'):tag('td') imageCell :addClass(args.imageclass) :css('padding', '0.2em 0 0.4em') :cssText(args.imagestyle) :wikitext(args.image) if args.caption then imageCell :tag('div') :css('padding-top', '0.2em') :css('line-height', '1.2em') :cssText(args.captionstyle) :wikitext(args.caption) end end if args.above then root :tag('tr') :tag('td') :addClass(args.aboveclass) :css('padding', '0.3em 0.4em 0.3em') :css('font-weight', 'bold') :cssText(args.abovestyle) :newline() -- newline required for bullet-points to work :wikitext(args.above) end local rowNums = {} for k, v in pairs(args) do k = '' .. k local num = k:match('^heading(%d+)$') or k:match('^content(%d+)$') if num then table.insert(rowNums, tonumber(num)) end end table.sort(rowNums) -- remove duplicates from the list (e.g. 3 will be duplicated if both heading3 and content3 are specified) for i = #rowNums, 1, -1 do if rowNums[i] == rowNums[i - 1] then table.remove(rowNums, i) end end for i, num in ipairs(rowNums) do local heading = args['heading' .. num] if heading then root :tag('tr') :tag('th') :addClass(args.headingclass) :css('padding', '0.1em') :cssText(args.basestyle) :cssText(args.headingstyle) :cssText(args['heading' .. num .. 'style']) :newline() :wikitext(heading) end local content = args['content' .. num] if content then root :tag('tr') :tag('td') :addClass(args.contentclass) :css('padding', '0 0.1em 0.4em') :cssText(args.contentstyle) :cssText(args['content' .. num .. 'style']) :newline() :wikitext(content) :done() :newline() -- Without a linebreak after the </td>, a nested list like "* {{hlist| ...}}" doesn't parse correctly. end end if args.below then root :tag('tr') :tag('td') :addClass(args.belowclass) :css('padding', '0.3em 0.4em 0.3em') :css('font-weight', 'bold') :cssText(args.belowstyle) :newline() :wikitext(args.below) end if not child then local navbarArg = args.navbar or args.tnavbar if navbarArg ~= 'none' and navbarArg ~= 'off' and (args.name or frame:getParent():getTitle():gsub('/sandbox$', '') ~= 'Шаблон:Sidebar') then root :tag('tr') :tag('td') :css('text-align', 'right') :css('font-size', '115%') :cssText(args.navbarstyle or args.tnavbarstyle) :wikitext(navbar{ args.name, mini = 1, fontstyle = args.navbarfontstyle or args.tnavbarfontstyle }) end end return tostring(root) end function p.collapsible(frame) local args = getArgs(frame) args.abovestyle = 'border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;' .. (args.abovestyle or '') args.belowstyle = 'border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;' .. (args.belowstyle or '') args.navbarstyle = 'padding-top: 0.6em;' .. (args.navbarstyle or args.tnavbarstyle or '') if not args.name and frame:getParent():getTitle():gsub('/sandbox$', '') == 'Шаблон:Sidebar with collapsible lists' then args.navbar = 'none' end local contentArgs = {} for k, v in pairs(args) do local num = string.match(k, '^list(%d+)$') if num then local expand = args.expanded and (args.expanded == 'all' or args.expanded == args['list' .. num .. 'name']) local row = mw.html.create('div') row :addClass('NavFrame') :addClass((not expand) and 'collapsed' or nil) :css('border', 'none') :css('padding', 0) :cssText(args.listframestyle) :cssText(args['list' .. num .. 'framestyle']) :tag('div') :addClass('NavHead') :addClass(args.listtitleclass) :css('font-size', '105%') :css('background', 'transparent') :css('text-align', 'left') :cssText(args.basestyle) :cssText(args.listtitlestyle) :cssText(args['list' .. num .. 'titlestyle']) :wikitext(trimAndAddAutomaticNewline(args['list' .. num .. 'title'] or 'List')) :done() :tag('div') :addClass('NavContent') :addClass(args.listclass) :addClass(args['list' .. num .. 'class']) :css('font-size', '105%') :css('padding', '0.2em 0 0.4em') :css('text-align', 'center') :cssText(args.liststyle) :cssText(args['list' .. num .. 'style']) :wikitext(trimAndAddAutomaticNewline(args['list' .. num])) contentArgs['content' .. num] = tostring(row) end end for k, v in pairs(contentArgs) do args[k] = v end return p.sidebar(frame, args) end return p e8d033060367055f925583e3102d31899d0dce9d Модуль:Navbox 828 82 139 138 2024-08-09T17:05:21Z Ксеноморф 2 1 версия импортирована: Импортировано из Русской Википедии Scribunto text/plain -- -- Реализует {{навигационная таблица}}, {{подгруппы навигационной таблицы}} и {{навигационная таблица с блоками}}. -- Основной объём кода заимствован из английского Module:Navbox. -- local p = {} local navbar = require('Module:Navbar')._ruwikiNavbar local getArgs -- lazily initialized local yesno -- lazily initialized local styleratio local ODD_EVEN_MARKER = '\127_ODDEVEN_\127' local RESTART_MARKER = '\127_ODDEVEN0_\127' local REGEX_MARKER = '\127_ODDEVEN(%d?)_\127' -- общие параметры для всех шаблонов local commonAliases = { name = {'name', 'имя'}, navigation = {'navigation', 'навигация'}, navbar = {'navbar', 'ссылка_на_просмотр'}, state = {'state'}, orphan = {'orphan'}, tracking = {'tracking'}, border = {'border', 1}, title = {'title', 'заголовок'}, titlegroup = {'titlegroup'}, above = {'above', 'вверху'}, image = {'image', 'изображение'}, imageleft = {'imageleft', 'изображение2', 'изображение_слева'}, below = {'below', 'внизу'}, bodyclass = {'bodyclass', 'класс_тела'}, titleclass = {'titleclass', 'класс_заголовка'}, titlegroupclass = {'titlegroupclass'}, aboveclass = {'aboveclass', 'класс_вверху'}, belowclass = {'belowclass', 'класс_внизу'}, groupclass = {'groupclass', 'класс_групп'}, listclass = {'listclass', 'класс_списков'}, imageclass = {'imageclass', 'класс_изображения'}, basestyle = {'basestyle', 'стиль', 'стиль_базовый'}, bodystyle = {'style', 'bodystyle', 'стиль_тела'}, titlestyle = {'titlestyle', 'стиль_основного_заголовка', 'стиль_заголовка'}, titlegroupstyle = {'titlegroupstyle'}, innerstyle = {'innerstyle'}, abovestyle = {'abovestyle', 'стиль_вверху'}, belowstyle = {'belowstyle', 'стиль_внизу'}, imagestyle = {'imagestyle', 'стиль_изображения'}, imageleftstyle = {'imageleftstyle', 'imagestyle2', 'стиль_изображения_слева'}, } -- параметры {{навигационная таблица}} и {{подгруппы навигационной таблицы}} local standardAliases = { groupstyle = {'groupstyle', 'стиль_заголовков', 'стиль_групп'}, liststyle = {'liststyle', 'стиль_списков'}, evenodd = {'evenodd', 'чётные_нечётные', 'четные_нечетные'}, groupwidth = {'groupwidth', 'ширина_групп'}, listpadding = {'listpadding', 'отступ_списков'}, } -- параметры {{навигационная таблица}} и {{подгруппы навигационной таблицы}} с нумерацией local standardElementAliases = { group = {'group%s', 'заголовок%s', 'группа%s'}, list = {'list%s', 'список%s'}, groupstyle = {'group%sstyle', 'стиль_заголовка%s', 'стиль_группы%s'}, listclass = {'list%sclass', 'класс%sсписка', 'класс_списка%s'}, liststyle = {'list%sstyle', 'стиль_списка%s'}, listpadding = {'list%spadding'} } -- параметры {{навигационная таблица с блоками}} -- с нижнего подчеркивания начинаются параметры, конфликтующие с standardAliases local groupsParentAliases = { selected = {'selected', 'открытый_блок', 'развернуть'}, secttitlestyle = {'secttitlestyle', 'стиль_заголовков'}, _groupstyle = {'groupstyle', 'стиль_блоков'}, _liststyle = {'liststyle', 'стиль_списков', 'contentstyle'}, _listpadding = {'listpadding', 'отступ_списка', 'отступ_списков'} } -- параметры {{навигационная таблица с блоками}} с нумерацией local groupsChildAliases = { groupname = {'abbr%s', 'имя_блока%s', 'аббр%s'}, state = {'state%s'}, title = {'group%s', 'блок%s', 'заголовок%s', 'группа%s', 'sect%s', 'section%s', 'секция%s'}, list1 = {'list%s', 'список%s', 'content%s'}, image = {'image%s', 'изображение%s'}, imageleft = {'imageleft%s', 'изображение_слева%s'}, secttitlestyle = {'sect%stitlestyle', 'стиль%sзаголовка', 'стиль_секции%s'}, groupstyle = {'group%sstyle', 'стиль%sблока', 'стиль_группы%s', 'стиль_блока%s'}, listclass = {'list%sclass', 'класс%sсписка', 'класс_списка%s'}, liststyle = {'list%sstyle', 'стиль%sсписка', 'стиль_списка%s', 'content%sstyle'}, color = {'цвет%s'} } local function checkAliases(args, aliases, index) for _, alias in ipairs(aliases) do local arg if index then arg = args[string.format(alias, index)] else arg = args[alias] end if arg then return arg end end return nil end local function checkElAliases(args, name, index) return checkAliases(args, standardElementAliases[name], index) end local function concatStyles(t) local res for k, v in pairs(t) do if v then res = res and res .. ';' .. v or v end end return res end local function striped(wikitext, args) -- Return wikitext with markers replaced for odd/even striping. -- Child (subgroup) navboxes are flagged with a category that is removed -- by parent navboxes. The result is that the category shows all pages -- where a child navbox is not contained in a parent navbox. local orphanCat = '[[Категория:Навигационные шаблоны без родителя]]' if args.border == 'subgroup' and args.orphan ~= 'yes' then -- No change; striping occurs in outermost navbox. return wikitext .. orphanCat end local first, second = 'odd', 'even' if args.evenodd then if args.evenodd == 'swap' then first, second = second, first else first = args.evenodd second = first end end local changer if first == second then changer = first else local index = 0 changer = function (code) if code == '0' then -- Current occurrence is for a group before a nested table. -- Set it to first as a valid although pointless class. -- The next occurrence will be the first row after a title -- in a subgroup and will also be first. index = 0 return first end index = index + 1 return index % 2 == 1 and first or second end end local regex = orphanCat:gsub('([%[%]])', '%%%1') return (wikitext:gsub(regex, ''):gsub(REGEX_MARKER, changer)) -- () omits gsub count end local function addNewline(s) if s:match('^[*:;#]') or s:match('^{|') then return '\n' .. s ..'\n' else return s end end local function renderNavBar(titleCell, args) local currentFrame = mw.getCurrentFrame() if args.navbar ~= 'off' and args.navbar ~= 'plain' and (args.name or not currentFrame:getParent():getTitle():gsub('/песочница$', '') == 'Шаблон:Навигационная таблица') then --- Gear creation titleCell :tag('span') :addClass('navbox-gear') :css('float', 'left') :css('text-align', 'left') :css('width', '5em') :css('margin-right', '0.5em') :wikitext(navbar{ args.name, ['fontstyle'] = args.titlestyle or args.basestyle }) end end -- -- Title row -- local function renderTitleRow(tbl, args) if not args.title then return end local titleRow = tbl:tag('tr') if args.titlegroup then titleRow :tag('th') :attr('scope', 'row') :addClass('navbox-group') :addClass(args.titlegroupclass) :cssText(args.basestyle) :cssText(args.groupstyle) :cssText(args.titlegroupstyle) :wikitext(args.titlegroup) end local titleCell = titleRow:tag('th'):attr('scope', 'colgroup') if args.titlegroup then titleCell :css('border-left', '2px solid #fdfdfd') :css('width', '100%') end local titleColspan = 2 if args.imageleft then titleColspan = titleColspan + 1 end if args.image then titleColspan = titleColspan + 1 end if args.titlegroup then titleColspan = titleColspan - 1 end titleCell :cssText(args.basestyle) :cssText(args.titlestyle) :addClass('navbox-title') :attr('colspan', titleColspan) renderNavBar(titleCell, args) titleCell :tag('div') :attr('id', mw.uri.anchorEncode(args.title)) :addClass(args.titleclass) :css('font-size', '114%') :css('margin', '0 5em') :wikitext(addNewline(args.title)) end -- -- Above/Below rows -- local function getAboveBelowColspan(args) local ret = 2 if args.imageleft then ret = ret + 1 end if args.image then ret = ret + 1 end return ret end local function renderAboveRow(tbl, args) if not args.above then return end tbl:tag('tr') :tag('td') :addClass('navbox-abovebelow') :addClass(args.aboveclass) :cssText(args.basestyle) :cssText(args.abovestyle) :attr('colspan', getAboveBelowColspan(args)) :tag('div') :wikitext(addNewline(args.above)) end local function renderBelowRow(tbl, args) if not args.below then return end tbl:tag('tr') :tag('td') :addClass('navbox-abovebelow') :addClass(args.belowclass) :cssText(args.basestyle) :cssText(args.belowstyle) :attr('colspan', getAboveBelowColspan(args)) :tag('div') :wikitext(addNewline(args.below)) end -- -- List rows -- local function haveSubgroups(args) for i = 1, 23 do if checkElAliases(args, 'group', i) and checkElAliases(args, 'list', i) then return true end end return false end local function renderListRow(tbl, args, index, rowspan, rowArgs) local row = tbl:tag('tr') if index == 1 and args.imageleft then row :tag('td') :addClass('navbox-image') :addClass(args.imageclass) :css('width', '1px') :css('padding', '0px 7px 0px 0px') :cssText(args.imageleftstyle) :attr('rowspan', rowspan) :tag('div') :wikitext(addNewline(args.imageleft)) end if rowArgs.group then local groupCell = row:tag('th') groupCell :attr('scope', 'row') :addClass('navbox-group') :addClass(args.groupclass) :cssText(args.basestyle) :css('width', args.groupwidth or '1px') -- If groupwidth not specified, minimize width groupCell :cssText(args.groupstyle) :cssText(rowArgs.groupstyle) :wikitext(rowArgs.group) end local listCell = row:tag('td') if rowArgs.group then listCell :css('text-align', 'left') :css('border-left-width', '2px') :css('border-left-style', 'solid') else if haveSubgroups(args) then listCell :attr('colspan', 2) end end if not args.groupwidth then listCell:css('width', '100%') end local listText = rowArgs.list local oddEven = ODD_EVEN_MARKER if listText:sub(1, 12) == '</div><table' then -- Assume list text is for a subgroup navbox so no automatic striping for this row. oddEven = listText:find('<th[^>]*"navbox%-title"') and RESTART_MARKER or 'odd' end listCell :css('padding', '0px') :cssText(args.liststyle) :cssText(rowArgs.liststyle) :addClass('navbox-list') :addClass('navbox-' .. oddEven) :addClass(args.listclass) :addClass(rowArgs.listclass) :tag('div') :css('padding', rowArgs.listpadding or args.listpadding or '0em 0.25em') :wikitext(addNewline(listText)) if index == 1 and args.image then row :tag('td') :addClass('navbox-image') :addClass(args.imageclass) :css('width', '1px') :css('padding', '0px 0px 0px 7px') :cssText(args.imagestyle) :attr('rowspan', rowspan) :tag('div') :wikitext(addNewline(args.image)) end end -- -- Tracking categories -- local function needsChangetoSubgroups(args) for i = 1, 23 do if (checkElAliases(args, 'group', i)) and not (checkElAliases(args, 'list', i)) then return true end end return false end local function needsHorizontalLists(args) if args.border == 'subgroup' or args.tracking == 'no' then return false end local listClasses = { ['plainlist'] = true, ['hlist'] = true, ['hlist hnum'] = true, ['hlist hwrap'] = true, ['hlist vcard'] = true, ['vcard hlist'] = true, ['hlist vevent'] = true, ['hlist hlist-items-nowrap'] = true, ['hlist-items-nowrap'] = true, } return not (listClasses[args.listclass] or listClasses[args.bodyclass]) end -- local function hasBackgroundColors() -- return mw.ustring.match(titlestyle or '','background') or mw.ustring.match(groupstyle or '','background') or mw.ustring.match(basestyle or '','background') -- end local function isIllegible(args) if not styleratio then styleratio = require('Module:Color contrast')._styleratio end for key, style in pairs(args) do if tostring(key):match("style$") or tostring(key):match("^стиль") then if styleratio{mw.text.unstripNoWiki(style)} < 4.5 then return true end end end return false end local function getTrackingCategories(args) local cats = {} if needsChangetoSubgroups(args) then table.insert(cats, 'Навигационные шаблоны с ошибочным использованием заголовков') end if needsHorizontalLists(args) then table.insert(cats, 'Навигационные шаблоны без горизонтальных списков') end if isIllegible(args) then table.insert(cats, 'Потенциально нечитаемые навигационные шаблоны') end return cats end local function renderTrackingCategories(builder, args) local title = mw.title.getCurrentTitle() if title.namespace ~= 10 then return end -- not in template space local subpage = title.subpageText if subpage == 'doc' or subpage == 'песочница' or subpage == 'тесты' then return end for i, cat in ipairs(getTrackingCategories(args)) do builder:wikitext('[[Категория:' .. cat .. ']]') end end -- -- Main navbox tables -- local function renderMainTable(args, listnums) local tbl = mw.html.create('table') :addClass('nowraplinks') :addClass(args.bodyclass) if args.title and (args.state ~= 'plain' and args.state ~= 'off') then tbl :addClass('collapsible') :addClass(args.state or 'autocollapse') end tbl:css('border-spacing', 0) if args.border == 'subgroup' or args.border == 'none' then tbl :addClass('navbox-subgroup') :cssText(args.bodystyle) else -- regular navbox - bodystyle and style will be applied to the wrapper table tbl :addClass('navbox-inner') :css('background', 'transparent') :css('color', 'inherit') end tbl:cssText(args.innerstyle) renderTitleRow(tbl, args) renderAboveRow(tbl, args) for i, listnum in ipairs(listnums) do local rowArgs = { group = checkElAliases(args, 'group', listnum), list = checkElAliases(args, 'list', listnum), groupstyle = checkElAliases(args, 'groupstyle', listnum), listclass = checkElAliases(args, 'listclass', listnum), liststyle = checkElAliases(args, 'liststyle', listnum), listpadding = checkElAliases(args, 'listpadding', listnum) } renderListRow(tbl, args, i, #listnums, rowArgs) end renderBelowRow(tbl, args) return tbl end -- Read the arguments in the order they'll be output in, to make references number in the right order. local function readInTheRightOrder(args, groupAliases, listAliases) local _ _ = checkAliases(args, commonAliases.title) _ = checkAliases(args, commonAliases.above) for i = 1, 23 do _ = checkAliases(args, groupAliases, i) _ = checkAliases(args, listAliases, i) end _ = checkAliases(args, commonAliases.below) end function p._navbox(args) if not yesno then yesno = require('Module:Yesno') end local listnums = {} for k, v in pairs(args) do local listnum = ('' .. k):match('^list(%d+)$') or ('' .. k):match('^список(%d+)$') if listnum then table.insert(listnums, tonumber(listnum)) end end table.sort(listnums) args.border = mw.text.trim(args.border or args[1] or '') if args.border == 'child' then args.border = 'subgroup' end for argname, aliasesList in pairs(commonAliases) do args[argname] = checkAliases(args, aliasesList) end for argname, aliasesList in pairs(standardAliases) do args[argname] = checkAliases(args, aliasesList) end args.navigation = yesno(args.navigation, '') -- render the main body of the navbox local tbl = renderMainTable(args, listnums) -- render the appropriate wrapper around the navbox, depending on the border param local res = mw.html.create() if args.border == 'none' then local nav = res:tag('div') :attr('role', 'navigation') :node(tbl) if args.title then nav:attr('aria-labelledby', mw.uri.anchorEncode(args.title)) else nav:attr('aria-label', 'Навигационный шаблон') end if args.name and args.name ~= '-' then nav:attr('data-name', args.name) end if args.navigation == true then nav:attr('data-navboxnavigation', '1') elseif args.navigation == false then nav:attr('data-navboxnavigation', '0') end elseif args.border == 'subgroup' then -- We assume that this navbox is being rendered in a list cell of a parent navbox, and is -- therefore inside a div with padding:0em 0.25em. We start with a </div> to avoid the -- padding being applied, and at the end add a <div> to balance out the parent's </div> res :wikitext('</div>') -- XXX: hack due to lack of unclosed support in mw.html. :node(tbl) :wikitext('<div>') -- XXX: hack due to lack of unclosed support in mw.html. else local nav = res:tag('div') :attr('role', 'navigation') :addClass('navbox') :cssText(args.bodystyle) :node(tbl) if args.title then nav:attr('aria-labelledby', mw.uri.anchorEncode(args.title)) else nav:attr('aria-label', 'Навигационный шаблон') end if args.name and args.name ~= '-' then nav:attr('data-name', args.name) end if args.navigation == true then nav:attr('data-navboxnavigation', '1') elseif args.navigation == false then nav:attr('data-navboxnavigation', '0') end end renderTrackingCategories(res, args) return striped(tostring(res), args) end function p.navbox(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end if not yesno then yesno = require('Module:Yesno') end args = getArgs(frame, {wrappers = {'Шаблон:Навигационная таблица', 'Шаблон:Подгруппы навигационной таблицы'}}) if frame.args.border then -- This allows Template:Navbox_subgroup to use {{#invoke:Navbox|navbox|border=...}}. args.border = frame.args.border end readInTheRightOrder(args, standardElementAliases.group, standardElementAliases.list) return p._navbox(args) end function p.navboxWithCollapsibleGroups(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end local args = getArgs(frame, {wrappers = {'Шаблон:Навигационная таблица с блоками'}}) readInTheRightOrder(args, groupsChildAliases.title, groupsChildAliases.list1) local parent = {} for argname, aliasesList in pairs(commonAliases) do parent[argname] = checkAliases(args, aliasesList) end for argname, aliasesList in pairs(groupsParentAliases) do parent[argname] = checkAliases(args, aliasesList) end for i = 1, 20 do local child = {} for argname, aliasesList in pairs(groupsChildAliases) do child[argname] = checkAliases(args, aliasesList, i) end child.color = child.color and string.format('background:%s;', child.color) or '' child.border = 'child' child.navbar = 'plain' if parent.selected and parent.selected == child.groupname then child.state = 'uncollapsed' end child.state = child.state or 'collapsed' child.basestyle = concatStyles{parent.basestyle, parent.secttitlestyle, child.secttitlestyle} child.titlestyle = concatStyles{parent._groupstyle, child.groupstyle, child.color} child.liststyle = concatStyles{parent._liststyle, child.liststyle} child.lispadding = parent._listpadding if child.title then parent['list' .. i] = p._navbox(child) else parent['list' .. i] = child.list1 end end return p._navbox(parent) end return p cf72974326d19e1d4d58d2d00766b944b3ca0944 Модуль:Карточка 828 83 141 140 2024-08-09T17:11:07Z Ксеноморф 2 1 версия импортирована: Импортировано из Русской Википедии Scribunto text/plain -- -- Модуль для реализации шаблона {{Карточка}} -- local p = {} local HtmlBuilder = require('Module:HtmlBuilder') local args = {} local origArgs local argsAliases = {} local root local function union(t1, t2) -- Возвращает объединение значений двух таблиц в виде последовательности. local vals = {} for k, v in pairs(t1) do vals[v] = true end for k, v in pairs(t2) do vals[v] = true end local ret = {} for k, v in pairs(vals) do table.insert(ret, k) end return ret end local function getArgNums(prefix) -- Возвращает таблицу индексов существующих полей с заданным префиксом, -- например, для префикса 'текст' и установленных 'текст1', 'текст2' и -- 'текст5' возвращает {1, 2, 5}. local nums = {} for k, v in pairs(args) do local num = tostring(k):match('^' .. prefix .. '([1-9]%d*)$') if num then table.insert(nums, tonumber(num)) end end table.sort(nums) return nums end local function addRow(rowArgs) -- Добавляет строку в карточку (заголовок или метку/текст). if rowArgs.header then root .tag('tr') .addClass(rowArgs.rowclass) .attr('id', rowArgs.rowid) .tag('th') .attr('colspan', 2) .attr('id', rowArgs.headerid) .addClass(rowArgs.class) .addClass(args['класс_заголовков']) .css('text-align', 'center') .cssText(args['стиль_заголовков']) .wikitext(rowArgs.header) elseif rowArgs.data then local row = root.tag('tr') row.addClass(rowArgs.rowclass) row.attr('id', rowArgs.rowid) if rowArgs.label then row .tag('th') .attr('scope', 'row') .attr('id', rowArgs.labelid) .cssText(args['стиль_меток']) .wikitext(rowArgs.label) .done() end local dataCell = row.tag('td') if not rowArgs.label then dataCell .attr('colspan', 2) .css('text-align', 'center') end dataCell .attr('id', rowArgs.dataid) .addClass(rowArgs.class) .cssText(rowArgs.datastyle) .newline() .wikitext(rowArgs.data) end end local function renderTitle() if not args['название'] then return end root .tag('caption') .addClass(args['класс_названия']) .cssText(args['стиль_названия']) .wikitext(args['название']) end local function renderAboveRow() if not args['вверху'] then return end root .tag('tr') .tag('th') .attr('colspan', 2) .addClass(args['класс_вверху']) .css('text-align', 'center') .css('font-size', '125%') .css('font-weight', 'bold') .cssText(args['стиль_вверху']) .wikitext(args['вверху']) end local function renderAbove2Row() if not args['вверху2'] then return end root .tag('tr') .tag('th') .attr('colspan', 2) .addClass(args['класс_вверху2']) .css('text-align', 'center') .css('font-style', 'oblique') .cssText(args['стиль_вверху2']) .wikitext(args['вверху2']) end local function renderBelowRow() if not args['внизу'] then return end root .tag('tr') .tag('td') .attr('colspan', 2) .addClass(args['класс_внизу']) .css('text-align', 'center') .cssText(args['стиль_внизу']) .newline() .wikitext(args['внизу']) end local function renderSubheaders() if args['подзаголовок'] then args['подзаголовок1'] = args['подзаголовок'] end if args['класс_ряда_подзаголовка'] then args['класс_ряда_подзаголовка1'] = args['класс_ряда_подзаголовка'] end local subheadernums = getArgNums('подзаголовок') for k, num in ipairs(subheadernums) do addRow({ data = args['подзаголовок' .. tostring(num)], datastyle = args['стиль_подзаголовков'] or args['стиль_подзаголовка' .. tostring(num)], class = args['класс_подзаголовков'], rowclass = args['класс_ряда_подзаголовка' .. tostring(num)] }) end end local function renderImages() if args['изображение'] then args['изображение1'] = args['изображение'] end if args['подпись'] then args['подпись1'] = args['подпись'] end local imagenums = getArgNums('изображение') for k, num in ipairs(imagenums) do local caption = args['подпись' .. tostring(num)] local data = HtmlBuilder.create().wikitext(args['изображение' .. tostring(num)]) if caption then data .tag('div') .cssText(args['стиль_подписи']) .wikitext(caption) end addRow({ data = tostring(data), datastyle = args['стиль_изображения'], class = args['класс_изображения'], rowclass = args['класс_ряда_изображения' .. tostring(num)] }) end end local function renderRows() -- Объединяет индексы заголовков и текстовых строк карточки -- и визуализирует их в правильном порядке через addRow. local rownums = union(getArgNums('заголовок'), getArgNums('текст')) table.sort(rownums) for k, num in ipairs(rownums) do addRow({ header = args['заголовок' .. tostring(num)], label = args['метка' .. tostring(num)], data = args['текст' .. tostring(num)], datastyle = args['стиль_текста'], class = args['класс' .. tostring(num)], rowclass = args['класс_ряда' .. tostring(num)], dataid = args['id_текста' .. tostring(num)], labelid = args['id_метки' .. tostring(num)], headerid = args['id_заголовка' .. tostring(num)], rowid = args['id_ряда' .. tostring(num)] }) end end local function renderNavBar() if not args['имя'] then return end root .tag('tr') .tag('td') .attr('colspan', 2) .css('text-align', 'right') .wikitext(mw.getCurrentFrame():expandTemplate({ title = 'Tnavbar', args = { args['имя'] } })) end local function isSet(x) -- Возвращает истину, если x задан и не пустой -- Внимание: отличается от enwiki! В enwiki проверяется на равенство 'yes' return x and x ~= '' end local function renderItalicTitle() -- Внимание: отличается от enwiki. В enwiki ожидается yes или force, здесь работает любое значение if isSet(args['заголовок_курсивом']) then root.wikitext(mw.getCurrentFrame():expandTemplate({title = 'Заголовок курсивом'})) end end local function renderTrackingCategories() if not isSet(args.nocat) then if #(getArgNums('текст')) == 0 and mw.title.getCurrentTitle().namespace == 0 then root.wikitext('[[Категория:Статьи с карточкой без заполненных данных]]') end if isSet(args['внедрение']) and args['название'] then root.wikitext('[[Категория:Статьи со встроенной карточкой и параметром названия]]') end end end local function _infobox() -- Задание общей страктуры карточки с добавлением стилей -- для карточек-потомков. if not isSet(args['внедрение']) then root = HtmlBuilder.create('table') root .addClass('infobox') .addClass(args['класс_тела']) if isSet(args['подкарточка']) then root .css('padding', '0') .css('border', 'none') .css('margin', '-2px') .css('width', 'auto') .css('min-width', '100%') .css('font-size', '100%') .css('clear', 'none') .css('float', 'none') .css('background-color', 'transparent') end -- Микроразметка if isSet(args['микр_тела']) then root .attr('itemscope', 'itemscope') .attr('itemtype', args['микр_тела']) end root .cssText(args['стиль_тела']) renderTitle() renderAboveRow() renderAbove2Row() else root = HtmlBuilder.create() root .wikitext(args['название']) end renderSubheaders() renderImages() renderRows() renderBelowRow() renderNavBar() renderItalicTitle() renderTrackingCategories() return tostring(root) end local function preprocessSingleArg(argName) -- Добавляет аргумент в таблицу аргументов, если он определён и не пустой. -- Пустые аргументы не обрабатываются, как и в ParserFunctions. if origArgs[argName] and origArgs[argName] ~= '' then args[argName] = origArgs[argName] end end local function translateArg(aliasArgName,localArgName) -- Функция добавляет поддержку алиасов параметров (например, на другом языке) -- Добавляем алиас параметра в таблицу алиасов -- Для одного параметра может быть несколько алиасов -- Нумерованные параметры(текст1 и т.д.) заносятся без номера if not argsAliases[localArgName] then argsAliases[localArgName] = {} end table.insert(argsAliases[localArgName], aliasArgName) -- Пока для тестирования: значения алиасов добавляются в таблицу аргументов -- Нумерованные параметры работать не будут if origArgs[localArgName] and origArgs[localArgName] ~= '' then -- параметр уже задан на локальном языке else -- если алиас задан и не пустой if origArgs[aliasArgName] and origArgs[aliasArgName] ~= '' then origArgs[localArgName] = origArgs[aliasArgName] end end end local function preprocessArgs(prefixTable, step) -- Сохраняет параметры с заданными префиксами в таблицу args, последовательно обходя -- аргументы в нужном порядке и с нужным шагом. Благодаря этому сноски и пр. появляются -- в правильном порядке. prefixTable — массив таблиц, каждая из которых может содержать -- два поля: поле-строку префикса (обязательно) и поле-таблицу зависимых параметров. -- Эта функция всегда обрабатывает параметры с префиксом, но зависимые параметры -- обрабатываются, только если параметр с префиксом задан и не пустой. if type(prefixTable) ~= 'table' then error("В качестве таблицы префиксов должна использоваться таблица", 2) end if type(step) ~= 'number' then error("Недопустимый тип параметра шага", 2) end -- Проверка правильности данных и обработка параметров без суффиксов. for i,v in ipairs(prefixTable) do if type(v) ~= 'table' or type(v.prefix) ~= "string" or (v.depend and type(v.depend) ~= 'table') then error('Недопустимая таблица префиксов preprocessArgs', 2) end preprocessSingleArg(v.prefix) -- Зависимые параметры обрабатываются, только если параметр с префиксом задан и не пустой. if args[v.prefix] and v.depend then for j, dependValue in ipairs(v.depend) do if type(dependValue) ~= 'string' then error('Недопустимый тип зависимого параметра в таблице preprocessArgs') end preprocessSingleArg(dependValue) end end end -- Обход нумерованных аргументов. local a = 1 -- Переменная-счётчик. local moreArgumentsExist = true while moreArgumentsExist == true do moreArgumentsExist = false for i = a, a + step - 1 do for j,v in ipairs(prefixTable) do local prefixArgName = v.prefix .. tostring(i) if origArgs[prefixArgName] then moreArgumentsExist = true -- Искать аргументы дальше, если был хотя бы один (в т. ч. пустой) preprocessSingleArg(prefixArgName) end -- Обрабатываем зависимые аргументы, если определена таблица зависимостей, -- а также задан не пустой аргумент с префиксом, либо обрабатывается -- "префикс1" и "префикс" задан (например, "изображение1" является синонимом для "изображение"). if v.depend and (args[prefixArgName] or (i == 1 and args[v.prefix])) then for j,dependValue in ipairs(v.depend) do local dependArgName = dependValue .. tostring(i) preprocessSingleArg(dependArgName) end end end end a = a + step end end function p.infobox(frame) -- При запуске через #invoke аргументы передаются через стандартную систему. -- При тестировании также можно передавать таблицу аргументов через frame. if frame == mw.getCurrentFrame() then origArgs = frame:getParent().args else origArgs = frame end -- Поддержка параметров из англовики translateArg('child','внедрение') translateArg('bodyclass','класс_тела') translateArg('subbox','подкарточка') translateArg('bodystyle','стиль_тела') translateArg('title','название') translateArg('titleclass','класс_названия') translateArg('titlestyle','стиль_названия') translateArg('above','вверху') translateArg('aboveclass','класс_вверху') translateArg('abovestyle','стиль_вверху') translateArg('subheader','подзаголовок') translateArg('subheaderrowstyle','стиль_подзаголовка') translateArg('subheaderrowclass','класс_подзаголовка') translateArg('subheaderstyle','стиль_подзаголовков') translateArg('subheaderclass','класс_подзаголовков') translateArg('image','изображение') translateArg('caption','подпись') translateArg('imagerowclass','класс_ряда_изображения') translateArg('captionstyle','стиль_подписи') translateArg('imagestyle','стиль_изображения') translateArg('imageclass','класс_изображения') translateArg('header','заголовок') translateArg('data','текст') translateArg('label','метка') translateArg('rowclass','класс_ряда') translateArg('class','класс') translateArg('dataid','id_текста') translateArg('labelid','id_метки') translateArg('headerid','id_заголовка') translateArg('rowid','id_ряда') translateArg('headerclass','класс_заголовков') translateArg('headerstyle','стиль_заголовков') translateArg('labelstyle','стиль_меток') translateArg('datastyle','стиль_текста') translateArg('below','внизу') translateArg('belowclass','класс_внизу') translateArg('belowstyle','стиль_внизу') translateArg('name','имя') --translateArg('italic title','заголовок_курсивом') --translateArg('','') -- Параметры обрабатываются по направлению чтения карточки, чтобы -- сноски и др. отображались в нужных местах. Параметры, зависящие -- от других параметров, обрабатываются только при наличии других параметров, -- чтобы в списке сносок не возникали нежелательные сноски. preprocessSingleArg('внедрение') preprocessSingleArg('класс_тела') preprocessSingleArg('подкарточка') preprocessSingleArg('стиль_тела') preprocessSingleArg('название') preprocessSingleArg('класс_названия') preprocessSingleArg('стиль_названия') preprocessSingleArg('вверху') preprocessSingleArg('класс_вверху') preprocessSingleArg('стиль_вверху') preprocessSingleArg('вверху2') preprocessSingleArg('класс_вверху2') preprocessSingleArg('стиль_вверху2') preprocessArgs({ {prefix = 'подзаголовок', depend = {'стиль_подзаголовка', 'класс_подзаголовка'}} }, 10) preprocessSingleArg('стиль_подзаголовков') preprocessSingleArg('класс_подзаголовков') preprocessArgs({ {prefix = 'изображение', depend = {'подпись', 'класс_ряда_изображения'}} }, 10) preprocessSingleArg('стиль_подписи') preprocessSingleArg('стиль_изображения') preprocessSingleArg('класс_изображения') preprocessArgs({ {prefix = 'заголовок'}, {prefix = 'текст', depend = {'метка'}}, {prefix = 'класс_ряда'}, {prefix = 'класс'}, {prefix = 'id_текста'}, {prefix = 'id_метки'}, {prefix = 'id_заголовка'}, {prefix = 'id_ряда'} }, 50) preprocessSingleArg('класс_заголовков') preprocessSingleArg('стиль_заголовков') preprocessSingleArg('стиль_меток') preprocessSingleArg('стиль_текста') preprocessSingleArg('внизу') preprocessSingleArg('класс_внизу') preprocessSingleArg('стиль_внизу') preprocessSingleArg('имя') preprocessSingleArg('заголовок_курсивом') preprocessSingleArg('nocat') return _infobox() end return p 2c8d650c985ea4b045be261f1a7a32917dfba56f Модуль:InfoboxImage 828 84 143 142 2024-08-09T17:12:19Z Ксеноморф 2 1 версия импортирована: Импортировано из Русской Википедии Scribunto text/plain -- Inputs: -- image - Can either be a bare filename (with or without the File:/Image: prefix) or a fully formatted image link -- size - size to display the image -- maxsize - maximum size for image -- sizedefault - default size to display the image if size param is blank -- alt - alt text for image -- title - title text for image -- border - set to yes if border -- center - set to yes, if the image has to be centered -- upright - upright image param -- suppressplaceholder - if yes then checks to see if image is a placeholder and suppresses it -- Outputs: -- Formatted image. -- More details available at the "Module:InfoboxImage/doc" page local i = {}; local yesno = require('Module:Yesno'); local placeholder_image = { "Blue - Replace this image female.svg", "Blue - Replace this image male.svg", "Female no free image yet.png", "Flag of None (square).svg", "Flag of None.svg", "Flag of.svg", "Green - Replace this image female.svg", "Green - Replace this image male.svg", "Image is needed female.svg", "Image is needed male.svg", "Location map of None.svg", "Male no free image yet.png", "Missing flag.png", "No flag.svg", "No free portrait.svg", "No portrait (female).svg", "No portrait (male).svg", "Red - Replace this image female.svg", "Red - Replace this image male.svg", "Replace this image female (blue).svg", "Replace this image female.svg", "Replace this image male (blue).svg", "Replace this image male.svg", "Silver - Replace this image female.svg", "Silver - Replace this image male.svg", } function i.IsPlaceholder(image) -- change underscores to spaces image = mw.ustring.gsub(image, "_", " "); -- if image starts with [[ then remove that and anything after | if mw.ustring.sub(image,1,2) == "[[" then image = mw.ustring.sub(image,3); image = mw.ustring.gsub(image, "([^|]*)|.*", "%1"); end -- Trim spaces image = mw.ustring.gsub(image, '^[ ]*(.-)[ ]*$', '%1'); -- remove file: or image: prefix if exists if mw.ustring.lower(mw.ustring.sub(image,1,5)) == "file:" then image = mw.ustring.sub(image,6); end if mw.ustring.lower(mw.ustring.sub(image,1,6)) == "image:" then image = mw.ustring.sub(image,7); end -- Trim spaces image = mw.ustring.gsub(image, '^[ ]*(.-)[ ]*$', '%1'); -- capitalise first letter image = mw.ustring.upper(mw.ustring.sub(image,1,1)) .. mw.ustring.sub(image,2); for i,j in pairs(placeholder_image) do if image == j then return true end end return false end function i.InfoboxImage(frame) local image = frame.args["image"]; if image == "" or image == nil then return ""; end if image == "&nbsp;" then return image; end if frame.args["suppressplaceholder"] == "yes" then if i.IsPlaceholder(image) == true then return ""; end end if mw.ustring.lower(mw.ustring.sub(image,1,5)) == "http:" then return ""; end if mw.ustring.lower(mw.ustring.sub(image,1,6)) == "[http:" then return ""; end if mw.ustring.lower(mw.ustring.sub(image,1,7)) == "[[http:" then return ""; end if mw.ustring.lower(mw.ustring.sub(image,1,6)) == "https:" then return ""; end if mw.ustring.lower(mw.ustring.sub(image,1,7)) == "[https:" then return ""; end if mw.ustring.lower(mw.ustring.sub(image,1,8)) == "[[https:" then return ""; end if mw.ustring.sub(image,1,2) == "[[" then -- search for thumbnail images and add to tracking cat if found if mw.title.getCurrentTitle().namespace == 0 and (mw.ustring.find(image, "|%s*thumb%s*[|%]]") or mw.ustring.find(image, "|%s*thumbnail%s*[|%]]")) then return image --.. "[[Категория:Страницы с миниатюрами в карточках]]"; else return image; end elseif mw.ustring.sub(image,1,2) == "{{" and mw.ustring.sub(image,1,3) ~= "{{{" then return image; elseif mw.ustring.sub(image,1,1) == "<" then return image; elseif mw.ustring.sub(image,1,5) == mw.ustring.char(127).."UNIQ" then -- Found strip marker at begining, so pass don't process at all return image; else local result = ""; local size = frame.args["size"]; local maxsize = frame.args["maxsize"]; local sizedefault = frame.args["sizedefault"]; local alt = frame.args["alt"]; local title = frame.args["title"]; local border = yesno(frame.args["border"]); local upright = frame.args["upright"] or ""; local center = yesno(frame.args["center"]); local caption = frame.args["caption"]; -- remove file: or image: prefix if exists if mw.ustring.lower(mw.ustring.sub(image,1,5)) == "file:" then image = mw.ustring.sub(image,6); end if mw.ustring.lower(mw.ustring.sub(image,1,6)) == "image:" then image = mw.ustring.sub(image,7); end if maxsize ~= "" and maxsize ~= nil then -- if no sizedefault then set to maxsize if sizedefault == "" or sizedefault == nil then sizedefault = maxsize end -- check to see if size bigger than maxsize if size ~= "" and size ~= nil then local sizenumber = tonumber(mw.ustring.match(size,"%d*")) or 0; local maxsizenumber = tonumber(mw.ustring.match(maxsize,"%d*")); if sizenumber>maxsizenumber and maxsizenumber>0 then size = maxsize; end end end -- add px to size if just a number if (tonumber(size) or 0) > 0 then size = size .. "px"; end result = "[[File:" .. image; if size ~= "" and size ~= nil then result = result .. "|" .. size; elseif sizedefault ~= "" and sizedefault ~= nil then result = result .. "|" .. sizedefault; else result = result .. "|frameless"; end if center then result = result .. "|center" end if alt ~= "" and alt ~= nil then result = result .. "|alt=" .. alt; end if border then result = result .. "|border"; end if upright ~= "" then result = result .. "|upright=" .. upright; end if title ~= "" and title ~= nil then result = result .. "|" .. title; elseif alt ~= "" and alt ~= nil then result = result .. "|" .. alt; end result = result .. "]]"; if caption ~= "" and caption ~= nil then result = result .. '<span class="media-caption" style="display:block">' .. caption .. '</span>'; end return result; end end return i; ec0754cf3050a84a661c48656d091d291822e37d Модуль:Ifempty 828 85 145 144 2024-08-09T17:13:23Z Ксеноморф 2 1 версия импортирована: Импортировано из Русской Википедии Scribunto text/plain local p = {} local getArgs = require('Module:Arguments').getArgs function p.main(frame) local args = getArgs(frame, {removeBlanks = false}) local before = args['до'] local after = args['после'] for i, v in ipairs(args) do if v ~= '' then return (before or '') .. v .. (after or '') end end end return p 875e8c9f03fb4cc02d80271ad3aaab13a9bcea86 Модуль:Check for unknown parameters 828 86 147 146 2024-08-09T17:13:50Z Ксеноморф 2 1 версия импортирована: Импортировано из Русской Википедии Scribunto text/plain -- This module may be used to compare the arguments passed to the parent -- with a list of arguments, returning a specified result if an argument is -- not on the list local p = {} local function trim(s) return s:match('^%s*(.-)%s*$') end local function isnotempty(s) return s and trim(s) ~= '' end function p.check (frame) local args = frame.args local pargs = frame:getParent().args local ignoreblank = isnotempty(frame.args['ignoreblank']) local showblankpos = isnotempty(frame.args['showblankpositional']) local knownargs = {} local unknown = frame.args['unknown'] or 'Found _VALUE_, ' local preview = frame.args['preview'] local values = {} local res = {} local regexps = {} -- create the list of known args, regular expressions, and the return string for k, v in pairs(args) do if type(k) == 'number' then v = trim(v) knownargs[v] = 1 elseif k:find('^regexp[1-9][0-9]*$') then table.insert(regexps, '^' .. v .. '$') end end if isnotempty(preview) then preview = '<div class="hatnote" style="color:red"><strong>Предупреждение:</strong> ' .. preview .. ' (это сообщение видно только при предпросмотре страницы).</div>' elseif preview == nil then preview = unknown end -- loop over the parent args, and make sure they are on the list for k, v in pairs(pargs) do if type(k) == 'string' and knownargs[k] == nil then local knownflag = false for i, regexp in ipairs(regexps) do if mw.ustring.match(k, regexp) then knownflag = true break end end if not knownflag and ( not ignoreblank or isnotempty(v) ) then k = mw.ustring.gsub(k, '[^%w\-_ ]', '?') table.insert(values, k) end elseif type(k) == 'number' and knownargs[tostring(k)] == nil and ( showblankpos or isnotempty(v) ) then local vlen = mw.ustring.len(v) v = mw.ustring.sub(v, 1, (vlen < 25) and vlen or 25) v = mw.ustring.gsub(v, '[^%w\-_ ]', '?') table.insert(values, k .. ' = ' .. v .. ((vlen >= 25) and ' ...' or '')) end end -- add resuls to the output tables if #values > 0 then if frame:preprocess( "{{REVISIONID}}" ) == "" then unknown = preview end for k, v in pairs(values) do if v == '' then -- Fix odd bug for | = which gets stripped to the empty string and -- breaks category links v = ' ' end local r = unknown:gsub('_VALUE_', v) table.insert(res, r) end end return table.concat(res) end function p.generate (frame) local res = '{{#invoke:check for unknown parameters|check\n' .. '|unknown=' .. frame.args['unknown'] .. '\n' local checkerparams = {'ignoreblank', 'preview', 'showblankpositional'} for _, v in pairs(checkerparams) do if frame.args[v] then res = res .. '|' .. v .. '=' .. frame.args[v] .. '\n' end end local templatenamespace = frame.args[1] local templatetitle = frame.args[2] local pagepointer = mw.title.new(templatetitle, templatenamespace) -- именно такой порядок! local text = pagepointer.getContent(pagepointer) local params = {} for param in string.gmatch(text, '\{\{\{([^\|\}]*)') do params[#params+1] = mw.text.trim(param) end table.sort(params) for k, v in pairs(params) do if k == 1 or v ~= params[k-1] then res = res .. '|' .. v end end res = res .. '}}' return res end return p 718ece7132a40acc051a3da4cdf668a76c02d10d Модуль:Navbar 828 87 149 148 2024-08-09T17:14:41Z Ксеноморф 2 1 версия импортирована: Импортировано из Русской Википедии Scribunto text/plain local p = {} local hlist = 'Template:Flatlist/styles.css' local templatestyles = 'Module:Navbar/styles.css' local getArgs function p._ruwikiNavbar( args ) local titleText = args[ 1 ] or (':' .. mw.getCurrentFrame():getParent():getTitle()) local title = mw.title.new(mw.text.trim(titleText), 'Template'); if not title then error('Invalid title ' .. titleText) end local whiteColorDefs = { ['#fff'] = true, ['#ffffff'] = true, ['white'] = true, } local fontColor = args.fontcolor and args.fontcolor:lower() local isWhite = fontColor and whiteColorDefs[ fontColor ] == true local fontStyle = args.fontstyle and mw.text.unstripNoWiki( args.fontstyle:lower() ) if not isWhite and fontStyle then local styleratio = require( 'Module:Color contrast' )._styleratio isWhite = styleratio( { fontStyle .. '; color:#666;', '', '#666' } ) < 3.66 end local isTemplate = title.namespace == 10 local altText = string.format( 'Перейти %s «%s»', isTemplate and 'к шаблону' or 'на страницу', mw.text.split( isTemplate and title.text or title.fullText, '#' )[ 1 ] ) return string.format( '[[Файл:Wikipedia interwiki section gear icon%s.svg|14px|class=noprint%s|link=%s|%s]]', isWhite and ' white' or '', isWhite and '' or ' skin-invert-image', tostring( title ), altText ) end function p.ruwikiNavbar(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end return p._ruwikiNavbar(getArgs(frame)) end function p._navbar(args) local titleArg = 1 if args.collapsible then titleArg = 2 if not args.plain then args.mini = 1 end if args.fontcolor then args.fontstyle = 'color:' .. args.fontcolor .. ';' end args.style = 'float:left; text-align:left; white-space:nowrap;' end if args[titleArg] == 'off' then return end local titleText = args[titleArg] or (':' .. mw.getCurrentFrame():getParent():getTitle()) local title = mw.title.new(mw.text.trim(titleText), 'Template'); if not title then error('Invalid title ' .. titleText) end local talkpage = title.talkPageTitle and title.talkPageTitle.fullText or ''; local tag if args.nodiv then tag = 'span' else tag = 'div' end local div = mw.html.create():tag(tag) div :addClass('navbar hlist plainlinks noprint') :attr('data-navboxnavigation-link', '0') :cssText(args.style) if args.mini then div:addClass('navbar-mini') end if not (args.mini or args.plain) then div :tag('span') :addClass('navbar-boxtext') :cssText(args.fontstyle) :wikitext(args.text or 'Шаблон:') :wikitext(' ') end local ul = div:tag('ul'); if args.brackets then ul:addClass('navbar-brackets') end ul :tag('li') :addClass('nv-view') :wikitext('[[' .. title.fullText .. '|') :tag(args.mini and 'abbr' or 'span') :addClass(args.mini and 'navbar-mini-abbr') :attr('title', 'Просмотр этого шаблона') :cssText(args.fontstyle) :wikitext(args.mini and 'п' or 'просмотр') :done() :wikitext(']]') :done() :tag('li') :addClass('nv-talk') :wikitext('[[' .. talkpage .. '|') :tag(args.mini and 'abbr' or 'span') :attr('title', 'Обсуждение этого шаблона') :cssText(args.fontstyle) :wikitext(args.mini and 'о' or 'обсуждение') :done() :wikitext(']]'); if not args.noedit then ul :tag('li') :addClass('nv-edit') :wikitext('[[Special:EditPage/' .. title.fullText .. '|') :tag(args.mini and 'abbr' or 'span') :attr('title', 'Править этот шаблон') :cssText(args.fontstyle) :wikitext(args.mini and 'р' or 'править') :done() :wikitext(']]'); end if args.collapsible then div:done() :tag('span') :addClass( args.mini and 'navbar-ct-mini' or 'navbar-ct-full' ) :cssText(args.fontstyle) :wikitext(args[1]) end local frame = mw.getCurrentFrame() return frame:extensionTag{ name = 'templatestyles', args = { src = hlist } } .. frame:extensionTag{ name = 'templatestyles', args = { src = templatestyles } } .. tostring(div:done()) end function p.navbar(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end return p._navbar(getArgs(frame)) end return p 695777e4dafbd5f7bf8b4f35d8db9349d08a363d Файл:Флаг Ксеноморфии.svg 6 88 150 2024-08-09T17:18:44Z Ксеноморф 2 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 152 150 2024-08-09T17:21:12Z DuOfOrl 5 DuOfOrl переименовал страницу [[Файл:Flag of Xenomorphia (1).svg]] в [[Файл:Флаг Ксеноморфии.svg]] без оставления перенаправления: Название с ошибкой wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 Файл:Coat of Arms of Xenomorphian Republic.png 6 89 151 2024-08-09T17:19:48Z Ксеноморф 2 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 Файл:Flag of the President of Xenomorphia.png 6 90 153 2024-08-09T17:21:14Z Ксеноморф 2 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 Модуль:Wikibase 828 92 157 156 2024-08-09T20:38:29Z DuOfOrl 5 1 версия импортирована Scribunto text/plain -- Модуль для функционала Викиданных local M = {}; local function tabletostr( t, fmt, s, o, c ) -- не для использования на страницах if type( t ) == "table" then local f = {}; for k, v in pairs( t ) do table.insert( f, string.format( fmt or '%s = %s', k, tabletostr( v, fmt, s, o, c ) ) ) end; table.sort( f ); return ( o or '' ) .. table.concat( f, s or '' ) .. ( c or '' ) else return tostring( t ) end end function M.wbview( ref, id ) -- вспом. функция для подписи из Викиданных local l = mw.wikibase.label( id ); return l and ( l == ref and l or ref .. '|' .. l .. ( mw.ustring.lower( l ) == mw.ustring.lower( ref ) and '' or '<sup>*</sup>' ) ) or ref end function M.id( frame ) -- Элемент текущей страницы в Викиданных --Если вызван с параметром, достаёт id значения данного свойства, иначе возвращает id страницы --Второй параметр - разделитель, если значений несколько ("; " по умолчанию), -- либо можно указать номер параметром n. Третий параметр - формат для строкового свойства, -- по умолчанию "%s" local function try() local e = mw.wikibase.getEntity(); if frame.args[ 1 ] then local function gv( i ) local z = e.claims[ frame.args[ 1 ] ][ i ].mainsnak.datavalue; if z.type == 'wikibase-entityid' then return z.value.id else return string.format( frame.args[ 3 ] or '%s', tabletostr( z.value, "%s", '; ', '{', '}' ) ) end end if frame.args[ 'n' ] then return gv( tonumber( frame.args[ 'n' ] ) ) end local p, h = e.claims[ frame.args[ 1 ] ], {} for n, v in pairs( p ) do h[ n ] = gv( n ) end return table.concat( h, frame.args[ 2 ] or "; " ) else return e.id end end local r, result = pcall( try ); if r then return result; else return '<strong class="error">В Викиданных нет записей для текущей страницы</strong>'; end end function M.struc( frame ) -- Отладочная функция, будет перенесена в отдельный модуль --Структуру см. [[mw:Extension:WikibaseClient/Lua#Entity table and data structure]] local function try() local i, e = 1, mw.wikibase.getEntity(); while frame.args[i] do e = e[ frame.args[ i ] ] or e[ tonumber( frame.args[ i ] ) ]; i = i + 1 end return tabletostr( e, frame.args[ 'f' ], frame.args[ 's' ] or '; ', '{', '}' ) end local r, result = pcall( try ); if r then return result; else return '<strong class="error">В Викиданных нет записей для текущей страницы</strong>'; end end function M.label( frame ) -- Комментарий к элементу Викиданных в 1-м параметре local function try() local id = frame.args[1]; if not id or id == '' then id = mw.wikibase.getEntityIdForCurrentPage(); -- error, если нет элемента end return mw.wikibase.label( id ); end local r, result = pcall( try ); if r then return result; else return '<strong class="error">В Викиданных нет записей для текущей страницы</strong>'; end end function M.description( frame ) local function try() local entityId = frame.args[1]; if not entityId or entityId == '' then entityId = mw.wikibase.getEntityIdForCurrentPage(); -- error, если нет элемента end return mw.wikibase.description( entityId ) end local r, result = pcall( try ); if r then return result; else return '<strong class="error">В Викиданных нет записей для указанной страницы</strong>'; end end function M.iwiki( frame ) -- Интервики для указанного языка (только с ВД) local function try() if frame.args[ 1 ] then return mw.wikibase.getEntity().sitelinks[ frame.args[ 1 ] .. 'wiki' ].title else-- список интервик local r = {}; for k, v in pairs( mw.wikibase.getEntity().sitelinks ) do table.insert( r, string.format( frame.args[ 'f' ] or "* [[:%s:%s]]\n", v.language, v.title ) ) end return table.concat( r ) end end local r, result = pcall( try ); if r then return result; else return '<strong class="error">В Викиданных нет записей для текущей страницы</strong>'; end end function M.iwikiall( frame ) -- Все ссылки, привязанные к элементу на ВД, в т.ч. викигид и склад local function try() if frame.args[ 1 ] then return mw.wikibase.getEntity().sitelinks[ frame.args[ 1 ] ].title else-- список интервик local r = {}; for k, v in pairs( mw.wikibase.getEntity().sitelinks ) do table.insert( r, string.format( frame.args[ 'f' ] or "* [[:%s:%s]]\n", v.language, v.title ) ) end return table.concat(r) end end local r, result = pcall( try ); if r then return result; else return ''; end end function M.page( frame ) -- страница Рувики для данного элемента local function try() return mw.wikibase.sitelink( frame.args[ 1 ] ) end local r, result = pcall( try ); if r then return result; else return '<strong class="error">В Викиданных нет записей для текущей страницы</strong>'; end end function M.wdprops( frame ) -- список всех свойств с ВД в человеко-читаемом виде local function try() local e, r = mw.wikibase.getEntity(), {}; for p, a in pairs( e.claims ) do local label = mw.wikibase.label( p ) or string.format( [[d:%s]], p ); local vals = {}; for n, v in pairs( a ) do local w = v.mainsnak.datavalue; vals[ n ] = ( w.type == 'wikibase-entityid' and '[[' .. M.wbview( mw.wikibase.sitelink( w.value.id ) or 'd:' .. w.value.id, w.value.id ) .. ']]' or M.tabletostr( w.value ) ) end table.insert( r, string.format( frame.args[ 'f' ] or '\n|-\n|rowspan=%i|%s\n|%s', #vals, label, table.concat( vals, frame.args[ 's' ] or '\n|-\n|' ) ) ) end--for return table.concat( r ) end local r, result = pcall( try ); if r then return result; else return '<strong class="error">В Викиданных нет записей для текущей страницы</strong>'; end end return M fc7c167bb9ef635b35a685123b273c486c229190 Шаблон:Рейтинг модуля 10 93 159 158 2024-08-09T20:43:36Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{Module other|{{ombox | type = notice | image = {{#switch: {{{1|}}} | pre-alpha | prealpha | pa | пре-альфа = [[File:Ambox warning blue construction.svg|40x40px|link=]] | alpha | a | альфа = [[File:Greek lc alpha icon.svg|26x26px|link=|class=skin-invert-image]] | beta | b | бета = [[File:Greek lc beta icon.svg|40x40px|link=|class=skin-invert-image]] | release | r | general | g | готов = [[File:Green check.svg|40x40px|link=]] | protected | protect | p | защищен = [[File:Padlock-silver.svg|40x40px|link=]] }} | style = | textstyle = | text = {{#switch: {{{1|}}} | pre-alpha | prealpha | pa | пре-альфа = Этот модуль оценён как [[:Категория:Модули:Пре-альфа версии|пре-альфа-версия]]. Он не закончен и может находиться в разработке. Он не должен использоваться в статьях. Модули остаются в этой стадии до тех пор, пока автор или кто-либо иной не сочтёт их структуру удовлетворительной.<!-- -->{{#switch: {{SUBPAGENAME}}|doc|sandbox=<!-- No category for /doc or /sandbox subpages --> | {{#ifeq: {{{nocat|}}} | true | <!-- No category if user sets nocat=true --> | [[Категория:Модули:Пре-альфа версии]] }} }} | alpha | a | альфа = Этот модуль оценён как [[:Категория:Модули:Альфа-версии|альфа-версия]]. Он готов для тестирований и может быть использован на небольшом количестве страниц для обнаружения проблем. Предложения по изменениям и дополнениям приветствуются.<!-- -->{{#switch: {{SUBPAGENAME}}|doc|sandbox=<!-- No category for /doc or /sandbox subpages --> | {{#ifeq: {{{nocat|}}} | true | <!-- No category if user sets nocat=true --> | [[Категория:Модули:Альфа-версии]] }} }} | beta | b | бета = Этот модуль оценён как [[:Категория:Модули:Бета-версии|бета-версия]]. Он готов для широкого применения, но должен применяться с осторожностью.<!-- -->{{#switch: {{SUBPAGENAME}}|doc|sandbox=<!-- No category for /doc or /sandbox subpages --> | {{#ifeq: {{{nocat|}}} | true | <!-- No category if user sets nocat=true --> | [[Категория:Модули:Бета-версии]] }} }} | release | r | general | g | готов = Этот модуль оценён как [[:Категория:Модули:Стабильные|готовый к использованию]]. Предполагается, что все баги устранены и он готов для широкого использования. Его можно указывать на справочных страницах и рекомендовать к использованию новым участникам. Для его изменения и тестирования, пожалуйста, [[ВП:ТЕСТЫ|используйте песочницу]].<!-- -->{{#switch: {{SUBPAGENAME}}|doc|sandbox=<!-- No category for /doc or /sandbox subpages --> | {{#ifeq: {{{nocat|}}} | true | <!-- No category if user sets nocat=true --> | [[Категория:Модули:Стабильные]] }} }} | protected | protect | p | защищен = Этот модуль относится к [[:Категория:Модули:Критические|критическим]]. У него очень много включений или он используется с подстановкой. Из-за опасности вандализма или ошибочного редактирования он был защищён.<!-- -->{{#switch: {{SUBPAGENAME}}|doc|sandbox=<!-- No category for /doc or /sandbox subpages --> | {{#ifeq: {{{nocat|}}} | true | <!-- No category if user sets nocat=true --> | [[Категория:Модули:Критические]] }} }} | #default = {{error|Рейтинг не указан или указан неправильно.}} }} }}|{{error|Этот шаблон должен использоваться в пространстве модулей.}}|demospace={{{demospace|<noinclude>module</noinclude>}}}}}<noinclude>{{doc}}</noinclude> c3380f20f70295631f2614caead4cbc73c110883 Шаблон:Module rating 10 94 160 2024-08-09T20:47:22Z DuOfOrl 5 Перенаправление на [[Шаблон:Рейтинг модуля]] wikitext text/x-wiki #REDIRECT [[Шаблон:Рейтинг модуля]] 4fffdbbfc33a362b03306003030f85ea1a516c19 Шаблон:Module other 10 95 162 161 2024-08-09T20:49:33Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{#switch: <!--If no or empty "demospace" parameter then detect namespace--> {{#if:{{{demospace|}}} | {{lc: {{{demospace}}} }} <!--Use lower case "demospace"--> | {{#ifeq:{{NAMESPACE}}|{{ns:Module}} | module | other }} }} | module = {{{1|}}} | other | #default = {{{2|}}} }}<!--End switch--><noinclude> {{doc}} <!-- Add categories and interwikis to the /doc subpage, not here! --> </noinclude> 097d5ea3648fcbbe0ccd87e8f217c713e97922c7 Международный аэропорт им.Азадырова Жщинькарху 0 96 163 2024-08-10T08:25:32Z Ксеноморф 2 Новая страница: «'''Международный аэропорт имени Азадырова Жщинькарху (код ИКАО: XLAH; код ИАТА: XAH)''' — второй и самый крупный аэропорт [[Ксеноморфленда]], а также крупнейший аэропорт в стране. Аэропорт был сдан в эксплуатацию в 2022 году и с тех пор стал важным узлом для между...» wikitext text/x-wiki '''Международный аэропорт имени Азадырова Жщинькарху (код ИКАО: XLAH; код ИАТА: XAH)''' — второй и самый крупный аэропорт [[Ксеноморфленда]], а также крупнейший аэропорт в стране. Аэропорт был сдан в эксплуатацию в 2022 году и с тех пор стал важным узлом для международного авиасообщения, обеспечивая связь Ксеноморфленда с различными направлениями по всему миру. == Общая информация == Аэропорт расположен в пригороде Жщинькарху, в 10 километрах от центра города. Это обеспечивает удобный доступ для пассажиров как на наземном транспорте, так и на такси. == Инфраструктура == Аэропорт им. Азадырова предлагает широкий спектр услуг для пассажиров, включая современные комфортабельные залы ожидания, кафе, рестораны, магазины беспошлинной торговли, а также услуги аренды автомобилей. В аэропорту работают представительства многих ксеноморфических авиакомпаний, а также информационные пункты, где пассажиры могут получить необходимую информацию. == Транспортные сообщения == Транспортное сообщение между аэропортом и городом хорошо организовано, что делает его доступным и удобным для пассажиров. Пользуясь автобусами и электропоездами, путешественники могут быстро и легко добраться до международного аэропорта им.Азадырова Жщинькарху из различных частей города. === Автобусное Движение === Международный аэропорт имени Азадырова Жщинькарху связан с городом с помощью пяти экспресс-маршрутов: - E673: [[Железнодорожный вокзал]] - Аэропорт - E882: [[Деловой центр]] - Аэропорт - E989: [[Район Эвервинд]] - Аэропорт - E1000: [[Пригородный вокзал]] - Аэропорт - E9813: [[Новберг]] - Аэропорт Автобусы на этих маршрутах следуют с минимальным количеством остановок и обеспечивают высокую скорость передвижения. Основными автомобилями, обслуживающими маршруты, являются [["MAN Lions City"]], за исключением маршрута E9813, который обслуживается автобусами [["MAN Lions Regio"]]. === Электропоезда === '''Станция "Международный аэропорт имени Азадырова Жщинькарху"''' была открыта 1 января 2022 года и является тупиковой станцией на отдельной ветке. Аэроэкспрессы обслуживают скоростные электропоезда, которые могут разгоняться до 120 км/ч. Поезда курсируют от пригородного вокзала и делают три остановки до аэропорта, что позволяет добраться до места назначения за 20 минут. Электричка ходит каждый час, обеспечивая комфортное и быстрое соединение с городом. 83839160a17b123981f9947d36acc7fe77774b71 164 163 2024-08-10T08:26:02Z Ксеноморф 2 wikitext text/x-wiki '''Международный аэропорт имени Азадырова Жщинькарху (код ИКАО: XLAH; код ИАТА: XAH)''' — второй и самый крупный аэропорт [[Ксеноморфленда]], а также крупнейший аэропорт в стране. Аэропорт был сдан в эксплуатацию в 2022 году и с тех пор стал важным узлом для международного авиасообщения, обеспечивая связь Ксеноморфленда с различными направлениями по всему миру. == Общая информация == Аэропорт расположен в пригороде Жщинькарху, в 10 километрах от центра города. Это обеспечивает удобный доступ для пассажиров как на наземном транспорте, так и на такси. == Инфраструктура == Аэропорт им. Азадырова предлагает широкий спектр услуг для пассажиров, включая современные комфортабельные залы ожидания, кафе, рестораны, магазины беспошлинной торговли, а также услуги аренды автомобилей. В аэропорту работают представительства многих ксеноморфических авиакомпаний, а также информационные пункты, где пассажиры могут получить необходимую информацию. == Транспортные сообщения == Транспортное сообщение между аэропортом и городом хорошо организовано, что делает его доступным и удобным для пассажиров. Пользуясь автобусами и электропоездами, путешественники могут быстро и легко добраться до международного аэропорта им.Азадырова Жщинькарху из различных частей города. === Автобусное Движение === Международный аэропорт имени Азадырова Жщинькарху связан с городом с помощью пяти экспресс-маршрутов: - E673: [[Железнодорожный вокзал]] - Аэропорт - E882: [[Деловой центр]] - Аэропорт - E989: [[Район Эвервинд]] - Аэропорт - E1000: [[Пригородный вокзал]] - Аэропорт - E9813: [[Новберг]] - Аэропорт Автобусы на этих маршрутах следуют с минимальным количеством остановок и обеспечивают высокую скорость передвижения. Основными автомобилями, обслуживающими маршруты, являются [["MAN Lions City"]], за исключением маршрута E9813, который обслуживается автобусами [["MAN Lions Regio"]]. === Электропоезда === '''Станция "Международный аэропорт имени Азадырова Жщинькарху"''' была открыта 1 января 2022 года и является тупиковой станцией на отдельной ветке. Аэроэкспрессы обслуживают скоростные электропоезда, которые могут разгоняться до 120 км/ч. Поезда курсируют от пригородного вокзала и делают три остановки до аэропорта, что позволяет добраться до места назначения за 20 минут. Электричка ходит каждый час, обеспечивая комфортное и быстрое соединение с городом. 18d7ab6499118ffd4f3dc5fae1d2f6041c282598 165 164 2024-08-10T08:29:32Z Ксеноморф 2 wikitext text/x-wiki '''Международный аэропорт имени Азадырова Жщинькарху (код ИКАО: XLAH; код ИАТА: XAH)''' — второй и самый крупный аэропорт [[Ксеноморфленда]], а также крупнейший аэропорт в [[Ксеноморфии]. Аэропорт был сдан в эксплуатацию в 2022 году и с тех пор стал важным узлом для международного авиасообщения, обеспечивая связь Ксеноморфленда с различными направлениями по всему миру. == Общая информация == Аэропорт расположен в пригороде Жщинькарху, в 10 километрах от центра города. Это обеспечивает удобный доступ для пассажиров как на наземном транспорте, так и на такси. == Инфраструктура == Аэропорт им. Азадырова предлагает широкий спектр услуг для пассажиров, включая современные комфортабельные залы ожидания, кафе, рестораны, магазины беспошлинной торговли, а также услуги аренды автомобилей. В аэропорту работают представительства многих ксеноморфических авиакомпаний, а также информационные пункты, где пассажиры могут получить необходимую информацию. == Транспортные сообщения == Транспортное сообщение между аэропортом и городом хорошо организовано, что делает его доступным и удобным для пассажиров. Пользуясь автобусами и электропоездами, путешественники могут быстро и легко добраться до международного аэропорта им.Азадырова Жщинькарху из различных частей города. === Автобусное Движение === Международный аэропорт имени Азадырова Жщинькарху связан с городом с помощью пяти экспресс-маршрутов: - E673: [[Железнодорожный вокзал]] - Аэропорт - E882: [[Деловой центр]] - Аэропорт - E989: [[Район Эвервинд]] - Аэропорт - E1000: [[Пригородный вокзал]] - Аэропорт - E9813: [[Новберг]] - Аэропорт Автобусы на этих маршрутах следуют с минимальным количеством остановок и обеспечивают высокую скорость передвижения. Основными автомобилями, обслуживающими маршруты, являются [["MAN Lions City"]], за исключением маршрута E9813, который обслуживается автобусами [["MAN Lions Regio"]]. === Электропоезда === '''Станция "Международный аэропорт имени Азадырова Жщинькарху"''' была открыта 1 января 2022 года и является тупиковой станцией на отдельной ветке. Аэроэкспрессы обслуживают скоростные электропоезда, которые могут разгоняться до 120 км/ч. Поезда курсируют от пригородного вокзала и делают три остановки до аэропорта, что позволяет добраться до места назначения за 20 минут. Электричка ходит каждый час, обеспечивая комфортное и быстрое соединение с городом. 487d34efc9243a942feb9d63232943ec99612ab5 166 165 2024-08-10T08:36:02Z Ксеноморф 2 wikitext text/x-wiki '''Международный аэропорт имени Азадырова Жщинькарху (код ИКАО: XLAH; код ИАТА: XAH)''' — второй и самый крупный аэропорт [[Ксеноморфленда]], а также крупнейший аэропорт в [[Ксеноморфии]. Аэропорт был сдан в эксплуатацию в 2022 году и с тех пор стал важным узлом для международного авиасообщения, обеспечивая связь Ксеноморфленда с различными направлениями по всему миру. Аэропорт расположен в пригороде Жщинькарху, в 10 километрах от центра города. Это обеспечивает удобный доступ для пассажиров как на наземном транспорте, так и на такси. Аэропорт служит хабом для авиакомпании [[Xenomorphiland Caeli]], а также является одним из главных аэропортов для [[Xenomorphia Airlines]] и [[Povaria Airlines]]. Местное население часто называет его XLAH — по его коду ICAO. == Инфраструктура == Аэропорт им. Азадырова предлагает широкий спектр услуг для пассажиров, включая современные комфортабельные залы ожидания, кафе, рестораны, магазины беспошлинной торговли, а также услуги аренды автомобилей. В аэропорту работают представительства многих ксеноморфических авиакомпаний, а также информационные пункты, где пассажиры могут получить необходимую информацию. == Транспортные сообщения == Транспортное сообщение между аэропортом и городом хорошо организовано, что делает его доступным и удобным для пассажиров. Пользуясь автобусами и электропоездами, путешественники могут быстро и легко добраться до международного аэропорта им.Азадырова Жщинькарху из различных частей города. === Автобусное Движение === Международный аэропорт имени Азадырова Жщинькарху связан с городом с помощью пяти экспресс-маршрутов: - E673: [[Железнодорожный вокзал]] - Аэропорт - E882: [[Деловой центр]] - Аэропорт - E989: [[Район Эвервинд]] - Аэропорт - E1000: [[Пригородный вокзал]] - Аэропорт - E9813: [[Новберг]] - Аэропорт Автобусы на этих маршрутах следуют с минимальным количеством остановок и обеспечивают высокую скорость передвижения. Основными автомобилями, обслуживающими маршруты, являются [https://ru.wikipedia.org/wiki/MAN_Lion%E2%80%99s_City/ "MAN Lions City"], за исключением маршрута E9813, который обслуживается автобусами [https://ru.wikipedia.org/wiki/MAN_Lion%E2%80%99s_Regio/ "MAN Lions Regio"]. === Электропоезда === '''Станция "Международный аэропорт имени Азадырова Жщинькарху"''' была открыта 1 января 2022 года и является тупиковой станцией на отдельной ветке. Аэроэкспрессы обслуживают скоростные электропоезда, которые могут разгоняться до 120 км/ч. Поезда курсируют от пригородного вокзала и делают три остановки до аэропорта, что позволяет добраться до места назначения за 20 минут. Электричка ходит каждый час, обеспечивая комфортное и быстрое соединение с городом. 0bffe43720d425625c7c81af9e5dbfee66487c4b 167 166 2024-08-10T08:36:50Z Ксеноморф 2 wikitext text/x-wiki '''Международный аэропорт имени Азадырова Жщинькарху (код ИКАО: XLAH; код ИАТА: XAH)''' — второй и самый крупный аэропорт [[Ксеноморфленда]], а также крупнейший аэропорт в [[Ксеноморфии]. Аэропорт был сдан в эксплуатацию в 2022 году и с тех пор стал важным узлом для международного авиасообщения, обеспечивая связь Ксеноморфленда с различными направлениями по всему миру. Аэропорт расположен в пригороде Жщинькарху, в 10 километрах от центра города. Это обеспечивает удобный доступ для пассажиров как на наземном транспорте, так и на такси. Аэропорт служит хабом для авиакомпании [[Xenomorphiland Caeli]], а также является одним из главных аэропортов для [[Xenomorphia Airlines]] и [[Povaria Airlines]]. Местное население часто называет его XLAH — по его коду ICAO. == Инфраструктура == Аэропорт им. Азадырова предлагает широкий спектр услуг для пассажиров, включая современные комфортабельные залы ожидания, кафе, рестораны, магазины беспошлинной торговли, а также услуги аренды автомобилей. В аэропорту работают представительства многих ксеноморфических авиакомпаний, а также информационные пункты, где пассажиры могут получить необходимую информацию. == Транспортные сообщения == Транспортное сообщение между аэропортом и городом хорошо организовано, что делает его доступным и удобным для пассажиров. Пользуясь автобусами и электропоездами, путешественники могут быстро и легко добраться до международного аэропорта им.Азадырова Жщинькарху из различных частей города. === Автобусное Движение === Международный аэропорт имени Азадырова Жщинькарху связан с городом с помощью пяти экспресс-маршрутов: - E673: [[Железнодорожный вокзал]] - Аэропорт - E882: [[Деловой центр]] - Аэропорт - E989: [[Район Эвервинд]] - Аэропорт - E1000: [[Пригородный вокзал]] - Аэропорт - E9813: [[Новберг]] - Аэропорт Автобусы на этих маршрутах следуют с минимальным количеством остановок и обеспечивают высокую скорость передвижения. Основными автомобилями, обслуживающими маршруты, являются [https://ru.wikipedia.org/wiki/MAN_Lion%E2%80%99s_City "MAN Lions City"], за исключением маршрута E9813, который обслуживается автобусами [https://ru.wikipedia.org/wiki/MAN_Lion%E2%80%99s_Regio "MAN Lions Regio"]. === Электропоезда === '''Станция "Международный аэропорт имени Азадырова Жщинькарху"''' была открыта 1 января 2022 года и является тупиковой станцией на отдельной ветке. Аэроэкспрессы обслуживают скоростные электропоезда, которые могут разгоняться до 120 км/ч. Поезда курсируют от пригородного вокзала и делают три остановки до аэропорта, что позволяет добраться до места назначения за 20 минут. Электричка ходит каждый час, обеспечивая комфортное и быстрое соединение с городом. 5bca896b84f351a4cc03d85e16e7d862f669456f 170 167 2024-08-10T08:47:29Z Ксеноморф 2 wikitext text/x-wiki '''Международный аэропорт имени Азадырова Жщинькарху (код ИКАО: XLAH; код ИАТА: XAH)''' — второй и самый крупный аэропорт [[Ксеноморфленда|https://memnotation.miraheze.org/wiki/%D0%9A%D1%81%D0%B5%D0%BD%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%BB%D0%B5%D0%BD%D0%B4]], а также крупнейший аэропорт в [[Ксеноморфии]]. Аэропорт был сдан в эксплуатацию в 2022 году и с тех пор стал важным узлом для международного авиасообщения, обеспечивая связь Ксеноморфленда с различными направлениями по всему миру. Аэропорт расположен в пригороде Жщинькарху, в 10 километрах от центра города. Это обеспечивает удобный доступ для пассажиров как на наземном транспорте, так и на такси. Аэропорт служит хабом для авиакомпании [[Xenomorphiland Caeli]], а также является одним из главных аэропортов для [[Xenomorphia Airlines]] и [[Povaria Airlines]]. Местное население часто называет его XLAH — по его коду ICAO. == Инфраструктура == Аэропорт им. Азадырова предлагает широкий спектр услуг для пассажиров, включая современные комфортабельные залы ожидания, кафе, рестораны, магазины беспошлинной торговли, а также услуги аренды автомобилей. В аэропорту работают представительства многих ксеноморфических авиакомпаний, а также информационные пункты, где пассажиры могут получить необходимую информацию. == Транспортные сообщения == Транспортное сообщение между аэропортом и городом хорошо организовано, что делает его доступным и удобным для пассажиров. Пользуясь автобусами и электропоездами, путешественники могут быстро и легко добраться до международного аэропорта им.Азадырова Жщинькарху из различных частей города. === Автобусное Движение === Международный аэропорт имени Азадырова Жщинькарху связан с городом с помощью пяти экспресс-маршрутов: - E673: [[Железнодорожный вокзал]] - Аэропорт - E882: [[Деловой центр]] - Аэропорт - E989: [[Район Эвервинд]] - Аэропорт - E1000: [[Пригородный вокзал]] - Аэропорт - E9813: [[Новберг]] - Аэропорт Автобусы на этих маршрутах следуют с минимальным количеством остановок и обеспечивают высокую скорость передвижения. Основными автомобилями, обслуживающими маршруты, являются [https://ru.wikipedia.org/wiki/MAN_Lion%E2%80%99s_City "MAN Lions City"], за исключением маршрута E9813, который обслуживается автобусами [https://ru.wikipedia.org/wiki/MAN_Lion%E2%80%99s_Regio "MAN Lions Regio"]. === Электропоезда === '''Станция "Международный аэропорт имени Азадырова Жщинькарху"''' была открыта 1 января 2022 года и является тупиковой станцией на отдельной ветке. Аэроэкспрессы обслуживают скоростные электропоезда, которые могут разгоняться до 120 км/ч. Поезда курсируют от пригородного вокзала и делают три остановки до аэропорта, что позволяет добраться до места назначения за 20 минут. Электричка ходит каждый час, обеспечивая комфортное и быстрое соединение с городом. 33e093d97f6f6bdff8ea9456c55f499b548b1690 171 170 2024-08-10T08:47:50Z Ксеноморф 2 wikitext text/x-wiki '''Международный аэропорт имени Азадырова Жщинькарху (код ИКАО: XLAH; код ИАТА: XAH)''' — второй и самый крупный аэропорт [[https://memnotation.miraheze.org/wiki/%D0%9A%D1%81%D0%B5%D0%BD%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%BB%D0%B5%D0%BD%D0%B4|Ксеноморфиленда]], а также крупнейший аэропорт в [[Ксеноморфии]]. Аэропорт был сдан в эксплуатацию в 2022 году и с тех пор стал важным узлом для международного авиасообщения, обеспечивая связь Ксеноморфленда с различными направлениями по всему миру. Аэропорт расположен в пригороде Жщинькарху, в 10 километрах от центра города. Это обеспечивает удобный доступ для пассажиров как на наземном транспорте, так и на такси. Аэропорт служит хабом для авиакомпании [[Xenomorphiland Caeli]], а также является одним из главных аэропортов для [[Xenomorphia Airlines]] и [[Povaria Airlines]]. Местное население часто называет его XLAH — по его коду ICAO. == Инфраструктура == Аэропорт им. Азадырова предлагает широкий спектр услуг для пассажиров, включая современные комфортабельные залы ожидания, кафе, рестораны, магазины беспошлинной торговли, а также услуги аренды автомобилей. В аэропорту работают представительства многих ксеноморфических авиакомпаний, а также информационные пункты, где пассажиры могут получить необходимую информацию. == Транспортные сообщения == Транспортное сообщение между аэропортом и городом хорошо организовано, что делает его доступным и удобным для пассажиров. Пользуясь автобусами и электропоездами, путешественники могут быстро и легко добраться до международного аэропорта им.Азадырова Жщинькарху из различных частей города. === Автобусное Движение === Международный аэропорт имени Азадырова Жщинькарху связан с городом с помощью пяти экспресс-маршрутов: - E673: [[Железнодорожный вокзал]] - Аэропорт - E882: [[Деловой центр]] - Аэропорт - E989: [[Район Эвервинд]] - Аэропорт - E1000: [[Пригородный вокзал]] - Аэропорт - E9813: [[Новберг]] - Аэропорт Автобусы на этих маршрутах следуют с минимальным количеством остановок и обеспечивают высокую скорость передвижения. Основными автомобилями, обслуживающими маршруты, являются [https://ru.wikipedia.org/wiki/MAN_Lion%E2%80%99s_City "MAN Lions City"], за исключением маршрута E9813, который обслуживается автобусами [https://ru.wikipedia.org/wiki/MAN_Lion%E2%80%99s_Regio "MAN Lions Regio"]. === Электропоезда === '''Станция "Международный аэропорт имени Азадырова Жщинькарху"''' была открыта 1 января 2022 года и является тупиковой станцией на отдельной ветке. Аэроэкспрессы обслуживают скоростные электропоезда, которые могут разгоняться до 120 км/ч. Поезда курсируют от пригородного вокзала и делают три остановки до аэропорта, что позволяет добраться до места назначения за 20 минут. Электричка ходит каждый час, обеспечивая комфортное и быстрое соединение с городом. 51168f65ffda900276d54361c20142f6cc76bdb6 172 171 2024-08-10T08:49:06Z Ксеноморф 2 wikitext text/x-wiki '''Международный аэропорт имени Азадырова Жщинькарху (код ИКАО: XLAH; код ИАТА: XAH)''' — второй и самый крупный аэропорт [[Ксеноморфиленд|Ксеноморфиленда]], а также крупнейший аэропорт в [[Ксеноморфии]]. Аэропорт был сдан в эксплуатацию в 2022 году и с тех пор стал важным узлом для международного авиасообщения, обеспечивая связь Ксеноморфленда с различными направлениями по всему миру. Аэропорт расположен в пригороде Жщинькарху, в 10 километрах от центра города. Это обеспечивает удобный доступ для пассажиров как на наземном транспорте, так и на такси. Аэропорт служит хабом для авиакомпании [[Xenomorphiland Caeli]], а также является одним из главных аэропортов для [[Xenomorphia Airlines]] и [[Povaria Airlines]]. Местное население часто называет его XLAH — по его коду ICAO. == Инфраструктура == Аэропорт им. Азадырова предлагает широкий спектр услуг для пассажиров, включая современные комфортабельные залы ожидания, кафе, рестораны, магазины беспошлинной торговли, а также услуги аренды автомобилей. В аэропорту работают представительства многих ксеноморфических авиакомпаний, а также информационные пункты, где пассажиры могут получить необходимую информацию. == Транспортные сообщения == Транспортное сообщение между аэропортом и городом хорошо организовано, что делает его доступным и удобным для пассажиров. Пользуясь автобусами и электропоездами, путешественники могут быстро и легко добраться до международного аэропорта им.Азадырова Жщинькарху из различных частей города. === Автобусное Движение === Международный аэропорт имени Азадырова Жщинькарху связан с городом с помощью пяти экспресс-маршрутов: - E673: [[Железнодорожный вокзал]] - Аэропорт - E882: [[Деловой центр]] - Аэропорт - E989: [[Район Эвервинд]] - Аэропорт - E1000: [[Пригородный вокзал]] - Аэропорт - E9813: [[Новберг]] - Аэропорт Автобусы на этих маршрутах следуют с минимальным количеством остановок и обеспечивают высокую скорость передвижения. Основными автомобилями, обслуживающими маршруты, являются [https://ru.wikipedia.org/wiki/MAN_Lion%E2%80%99s_City "MAN Lions City"], за исключением маршрута E9813, который обслуживается автобусами [https://ru.wikipedia.org/wiki/MAN_Lion%E2%80%99s_Regio "MAN Lions Regio"]. === Электропоезда === '''Станция "Международный аэропорт имени Азадырова Жщинькарху"''' была открыта 1 января 2022 года и является тупиковой станцией на отдельной ветке. Аэроэкспрессы обслуживают скоростные электропоезда, которые могут разгоняться до 120 км/ч. Поезда курсируют от пригородного вокзала и делают три остановки до аэропорта, что позволяет добраться до места назначения за 20 минут. Электричка ходит каждый час, обеспечивая комфортное и быстрое соединение с городом. e24df1f9955e5ea86db4284fd8c67df308e13f26 Ксеноморфиленд 0 97 168 2024-08-10T08:44:23Z Ксеноморф 2 Новая страница: «'''Ксеноморфиленд''' (ксен. Xenomorphiland), сокр. XML) — столица и крупнейший город [[Ксеноморфической Республики]], входящий в одну из крупнейших агломераций [[Мемного мира]], а также является вторым мегалополисом [[Шошалтаря]]. Население города составляет 8 765 075 чел...» wikitext text/x-wiki '''Ксеноморфиленд''' (ксен. Xenomorphiland), сокр. XML) — столица и крупнейший город [[Ксеноморфической Республики]], входящий в одну из крупнейших агломераций [[Мемного мира]], а также является вторым мегалополисом [[Шошалтаря]]. Население города составляет 8 765 075 человек, агломерации — 15,98 млн (оценка на 2024 год). Ксеноморфиленд является отдельным округом в составе КР, и не входит в состав ни одного региона, расположен в южной части Ксеноморфии рядом с [[Райтостаном]]. Впервые Ксеноморфиленд был упомянут в 3 веке до нашей эры, и изначально назывался Буссинградом, такое имя он носил до 1244 года, пока не был переименован в нынешнее наименование. Стал столицей Ксеноморфии в 1103 году. == История == === Буссиянское Царство === Ранее, Ксеноморфиленд назывался Буссинградом, где его населяли полностью буссияны, пока его не разгромили в 780 году ксеноморфическими племенами. === Ксеноморфическое Царство === В конце X века, Буссинград оффициально стал столицей Ксеноморфического царства, а в 1103 году, вовсе центром объединённой Чачазиатской Ксеноморфии. В 1244 году Буссинград был переименован в Ксеноморфиленд, из-за назреваемой в то время нужды в проведении Ксеноморфизации городов. === Ксеноморфическая Империя === ==== В период смуты ==== В 1690 году в Ксеноморфиленде и во всей империи прогремело восстание, которое спровоцировало начало распада Ксеноморфической Империи. 63f0527c19ba83f62f4edb6515c31811575ede69 169 168 2024-08-10T08:44:54Z Ксеноморф 2 wikitext text/x-wiki '''Ксеноморфиленд''' (ксен. Xenomorphiland), сокр. XML) — столица и крупнейший город [[Ксеноморфической Республики]], входящий в одну из крупнейших агломераций Мемного мира, а также является вторым мегалополисом [[Шошалтаря]]. Население города составляет 8 765 075 человек, агломерации — 15,98 млн (оценка на 2024 год). Ксеноморфиленд является отдельным округом в составе КР, и не входит в состав ни одного региона, расположен в южной части Ксеноморфии рядом с [[Райтостаном]]. Впервые Ксеноморфиленд был упомянут в 3 веке до нашей эры, и изначально назывался Буссинградом, такое имя он носил до 1244 года, пока не был переименован в нынешнее наименование. Стал столицей Ксеноморфии в 1103 году. == История == === Буссиянское Царство === Ранее, Ксеноморфиленд назывался Буссинградом, где его населяли полностью буссияны, пока его не разгромили в 780 году ксеноморфическими племенами. === Ксеноморфическое Царство === В конце X века, Буссинград оффициально стал столицей Ксеноморфического царства, а в 1103 году, вовсе центром объединённой Чачазиатской Ксеноморфии. В 1244 году Буссинград был переименован в Ксеноморфиленд, из-за назреваемой в то время нужды в проведении Ксеноморфизации городов. === Ксеноморфическая Империя === ==== В период смуты ==== В 1690 году в Ксеноморфиленде и во всей империи прогремело восстание, которое спровоцировало начало распада Ксеноморфической Империи. 69c2c545bf812c3dc4aa1fd2f70d4ccbd877ad5b 179 169 2024-08-10T10:38:08Z Ксеноморф 2 wikitext text/x-wiki '''Ксеноморфиленд''' (ксен. Xenomorphiland), сокр. XML) — столица и крупнейший город [[Ксеноморфия|Ксеноморфической Республики]], входящий в одну из крупнейших агломераций Мемного мира, а также является вторым мегалополисом [[Шошалтаря]]. Население города составляет 8 765 075 человек, агломерации — 15,98 млн (оценка на 2024 год). Ксеноморфиленд является отдельным округом в составе КР, и не входит в состав ни одного региона, расположен в южной части Ксеноморфии рядом с [[Райтостаном]]. Впервые Ксеноморфиленд был упомянут в 3 веке до нашей эры, и изначально назывался Буссинградом, такое имя он носил до 1244 года, пока не был переименован в нынешнее наименование. Стал столицей Ксеноморфии в 1103 году. == История == === Буссиянское Царство === Ранее, Ксеноморфиленд назывался Буссинградом, где его населяли полностью буссияны, пока его не разгромили в 780 году ксеноморфическими племенами. === Ксеноморфическое Царство === В конце X века, Буссинград оффициально стал столицей Ксеноморфического царства, а в 1103 году, вовсе центром объединённой Чачазиатской Ксеноморфии. В 1244 году Буссинград был переименован в Ксеноморфиленд, из-за назреваемой в то время нужды в проведении Ксеноморфизации городов. === Ксеноморфическая Империя === ==== В период смуты ==== В 1690 году в Ксеноморфиленде и во всей империи прогремело восстание, которое спровоцировало начало распада Ксеноморфической Империи. d1fb78d678af5f35a90ed415e4aa78d2330854e8 Ксеноморфия 0 98 173 2024-08-10T10:16:03Z Ксеноморф 2 Новая страница: «'''Ксеноморфия''' (ксен. '''Xəňomořphīæ''') или '''Ксеноморфическая Республика''' (ксен. Řĕpůbłīčæ Xəňomořphīčæ), сокращённо КР — государство во вселенной [[Мемный Мир]] на континенте Шошалтарь. Население — около 45 млн человек (2023, оценка). Ксеноморфия — федеративная п...» wikitext text/x-wiki '''Ксеноморфия''' (ксен. '''Xəňomořphīæ''') или '''Ксеноморфическая Республика''' (ксен. Řĕpůbłīčæ Xəňomořphīčæ), сокращённо КР — государство во вселенной [[Мемный Мир]] на континенте Шошалтарь. Население — около 45 млн человек (2023, оценка). Ксеноморфия — федеративная президентская республика, которая административно состоит из 20 автономных регионов (или же штатов), республик [[Абыкабия]], [[Ксеноморфическая Палестина]] и федеральных округов [[Ксеноморфиленд]] и [[Еаст-Ксеноморфиленд]]. == Первое упоминание и этимология == Первое упоминание Ксеноморфии - 3000 год до н.э, в этом году основалась первое Ксеноморфическое племя (правда к нынешним [[ксеноморфцам]] оно не имеет отношения, как и остальные племена [[Древней Ксеноморфии]], за исключением [[Буссиянского царства]]), затем же в 1200 году до н.э разрослась в полноценное государство. Название государства Ксеноморфия происходит от слова "Ксеноморф" (т. е. чужой), одноименного мифического существа. == История == === Зарождение Ксеноморфического государства === В 300 году на территориях нынешней Ксеноморфии появляется Буссиянское царство, которое изначально нейтрально относилось к недавно образованному племени Ксеноморфов, возникшему в 318 году как отголосок [[Буссиянского Царства]]. Однако с течением времени отношения между двумя формами жизни начали ухудшаться, что привело к конфликту. В 321 году началась [[Буссиянско-Ксеноморфная война]], в ходе которой Ксеноморфы пытались добиться создания собственной автономии. Конфликт продолжался три года, и, несмотря на упорное сопротивление, племена Ксеноморфов потерпели поражение. В результате этого поражения Буссиянцы урезали права Ксеноморфического народа, что вызвало резкое ухудшение условий жизни для многих ксеноморфов. Однако, в 326 году произошло важное событие — была создана [[Ксеноморфическая Уния]]. Это объединение дало возможность всем ксеноморфическим народам солидаризироваться и подготовиться к грядущим вызовам, включая будущие конфликты. Ситуация в самом Буссиянском царстве была крайне нестабильной и чуть позже привела к гражданской войне, которая началась в 343 году и продолжалась 42 года. Конфликт закончился в 385 году разгромом столицы [[Буссинграда]]. Это важное событие знаменует собой не только победу Ксеноморфов, но и трансформацию города в современный [[Ксеноморфиленд]] в 1244 году из-за назреваемой в то время нужды в проведении Ксеноморфизации городов, что стало знаковым моментом в истории региона. Победа в этой войне ознаменовала полное окончание античной эры для Ксеноморфического региона и открыла новую страницу в его развитии, сформировав культурные, политические и социальные основы, которые будут влиять на будущее Ксеноморфии. === Послевоенное время === В 430 году, после войны, Ксеноморфия официально изменила флаг Ксеноморфической Унии, который вскоре, станет символом [[Ксеноморфического Царства]]. в знак нового политического курса. Это событие символизировало начало новой эры в истории страны, обозначая отход от устаревших традиций. Флаг представляет с собой оригинальный Ксеноморфический флаг, без буквы К. В 780 году, Ксеноморфия окончательно уходит в монархию, и его переформировали в Царство. С образованием монархии в 780 году был установлен новый порядок и управляемость. Монархия предложила стабильность и структурированное правление, что дало возможность развиваться внутренним делам и укреплять границы. Но помимо него, в Ксеноморфии, кроме [[Неоморфии]] были множество других государств. Ксеноморфия начинает активное завоёвывание этих земель к себе. В результате успешных военных кампаний в 980 году Ксеноморфия завоевала [[Сан-Канфунсберскую Империю]], а уже закончив с [[Владиславовом]], Ксеноморфическое Царство смогло полностью объединить всю Ксеноморфию без Неоморфии, а её главным центром стал город Буссинград. Это событие привело к смене династии, что существенно повлияло на политическую карту региона. Буссинград, ранее известный как центр торговли и культуры, был переименован в Ксеноморфиленд в 1244 году. Это изменение имени подчеркнуло значимость столицы в истории Ксеноморфии и её культуру. С приходом к власти первого императора [[Ксеноморфа I]] в 1400 году также произошла смена флага Ксеноморфии на имперский. Этот момент стал важным символом единства и силы страны. В 1401 году началась новая эра — эра Ксеноморфической Империи. Это время отмечено экспансией и укреплением влияния Ксеноморфии на международной арене. К 1450 году Ксеноморфия значительно расширила свои границы, завоевав соседние страны и [[Больманские острова]]. Эти достижения укрепили империю как мощную силу в регионе. === Первое тысячилетие === В 1100 году Ксеноморфия ввязывается в войну с [[племенами Альтов]]. Побеждая Альтов, ксеноморфы смогли присоединить их территории к себе, что стало началом освоения [[Неоморфии]]. Этот процесс продолжался на протяжении трех столетий и сыграл ключевую роль в расширении границ Ксеноморфии. В этом-же году, после более чем трехсот лет освоения и войн, Ксеноморфия преобразуется в Ксеноморфическую Империю. Этот переход к имперскому статусу символизировал укрепление власти и влияние Ксеноморфии на международной арене и империя добивается значительных успехов, захватив множество новых территорий, включая Больманские острова. Однако уже в конце года император Ксеноморф I умирает. Поскольку его сын, [[Ксеноморф II]], еще был младенцем, власть переходит к его матери, обеспечивая временную стабильность. В 1468 году, по достижении совершеннолетия, Ксеноморф II был венчан императором. Его правление стало важным этапом в истории, обеспечивая внутренний мир и развитие империи. Ксеноморф II умер в 1555 году после 55 лет правления, оставив за собой наследие империи, но также вызвав вопросы о следующем правопреемнике. После восшествия на трон его сына [[Ксеноморфа III]], который пришел к власти в 1603 году, ситуация в стране ухудшается, граждане-заговорщики, подняли восстания из-за династического застоя, из-за власти, чья руководила Ксеноморфией не смогла выбрать себя приемника Ксеноморфа III, из-за её короткого правления, и его расстрела. и начало кризиса. В 1651 году он был убит в результате заговора, оставив империю без ясного наследника и ведя к династическую кризису. В стране также начался экономический кризись, страна не модернизировалось, и просто стояло на месте и не развивалась. И эти причины спровоцировали восстание 1690 года, которое за короткое время, охватила всю территорию Ксеноморфии того времени, власти империи решили, что лучшей проблемой прекращение бунт, это собственно подавление, в 1691 году, восстание очень жёстко подавлено, а все её участники казнены, общество не расценило такой случай, и начали вооружатся. Что привело к ещё одному восстание, которое было куда более масштабнее чем предыдущее. [[Долбик Маппер]], воспользовавшись смятением в империи, начал свое правление, забирая земли Ксеноморфической Империи. С 1690 года начались массовые митинги по всей империи, которые в конечном итоге привели к потере контроля над территориями. Всё это закончилось тем, что в 1695 начался распад, регионы уходили за регионами, империя распадается как карточный домик. Протестующие начали требовать перемен, что в итоге привело к распаду империи к 1700 году. Этот период историки рассматривают как худший в истории Ксеноморфии. === Послеимперское время === Всё это закончилось в 1702, когда от Империи осталось ничего, Ксеноморфическая Империя была потеряна, и была сожжена в пепел, в оставшихся землях произошло ещё одно восстание, которое перерасло в долгую 12-ти летнюю гражданскую войну между Севером и Югом. Северяне - люди, чьи идеи были восстановить монархию и попытки вернуть Империю, а южане - люди, чьи идеи уже стояли за республику и либерализм. По итогу которой, южане, в 1714 году при помощи средств и основных снабжений из Ксеноморфиленд, выиграли гражданскую войну, и теперь все мы знаем такую Ксеноморфию, которая есть и сейчас. Страна переменила свою форму правления на парламентскую республику, установив новые демократические принципы и закладывая основы для будущего развития в 1780 году. В 1913 году Ксеноморфия столкнулась с экономическим кризисом, который оказал серьезное влияние на внутренние дела страны и создал политическую нестабильность. Экономические трудности привели к ухудшению жизненных условий населения и росту недовольства. В 1914 году Ксеноморфия вступила в [[Первую Мемную войну]], пытаясь укрепить свои позиции. Эта война потребовала значительных ресурсов и оставила страну истощенной. Параллельно с войной, с 1914 по 1916 годы, Ксеноморфия столкнулась с Абыкабским исламским восстанием. Восстание было жестко подавлено, но это оставило глубокие раны в обществе и усугубило внутренние конфликты. После череды пограничных провокаций со стороны [[Османской Империи]] в 1915 году, Ксеноморфия официально присоединилась к Первой Мемной войне. Это решение требовало еще большего напряжения ресурсов, участников и времени. В 1917 году после революции была сформирована временная либеральная правительственная структура. Это правительство стремилось к демократическим реформам и поиску путей выхода из кризиса, несмотря на попытки правительственной перестройки, в 1918 году в Ксеноморфии произошла [[коммунистическая революция]], которая была подавлена. В результате была сохранена [[Первая Ксеноморфическая Республика]]. К тому же, страна одержала победу в Первой Мемной войне, что позволило ей участвовать в создании Лиги Наций. В 1922 году был проведен ряд экономических реформ, направленных на восстановление экономики и повышение жизненного уровня населения после кризиса, последовавшего за войной. В 1928 году в стране была проведена конституционная реформа, которая привела к смене флага на «Новый национальный флаг Ксеноморфии». Этот символ перемен стал знаком новой надежды и единства. В 1930 году началась [[Великая Ксеноморфическая Война]]. [[Райтостанские войска]] во главе с командиром Долбиком атаковал земли Ксеноморфии. Ксеноморфия после [[потери столицы]] в 1934 году [[капитулировала]], но оставшиеся силы которые сражались за независимость в Абыкабии, Неоморфии, [[Иркарии]] и [[Ксеноморфической Палестине]], не признали поражение Ксеноморфии в войне и отделились, чтобы сражаться до последнего. В 1935 году началось [["Чёрное десятилетие"]] и [[Великая депрессия]]. В 1938 году на [[территории оккупированной Райтостаном Ксеноморфии]] произошли митинги ксеноморфического населения, которые были жёстко подавлены. В 1940 году, пока в остальном Шошалтаре разгорелась [[Вторая Мемная Война]]. Оставшиеся генералитет и правительство павшей Ксеноморфии, закрепившееся в Больманских островах, ударили в тыл врага, что было на руку солдатам Неоморфии, Абыкабии, Иркарии и Ксеноморфической Палестине в то время, и они существенно оттеснили врага. [[Федерация Мобиановских Островов]], [[Финкория]] и [[Пчеляндия]] активно помогают и спонсируют Ксеноморфию, а [[Райтостан]] вступает в [[Ось]]. 7 декабря 1941, после японской [[атаки на Пёрл-Харбор]], [[цоиновский нацисткий генералитет]] без объявления войны вторглась в территорию Ксеноморфии. Что было на руку Райтостану, и они вместе оттеснили Ксеноморфийцев, но в 1943 году Цоиновия, после [[Сталинградской битвы]] и Райтостан были ослаблены. [[Ксеноморфическое войско]] начало своё контр.наступление, входе которой она освободила Неоморфию, Ксеноморфиленд, [[Сан-Канфусберг]], открыший прямой путь в Райтостан, и 3 марта 1945 года, после того как в главном здании Райтостана взвился Ксеноморфический флаг, Райтостан подписал акт о безоговорочной капитуляции Райтостана. Ксеноморфическая Освободительная Армия смогла сделать Ксеноморфию полностью независимой. Теперь [[3 марта]] полностью является государственным праздником. === КР в период Холодной войны === ==== Начало холодной войны и Движение за гражданские права (1945—1964) ==== В истории КР 1945—1964 годы были периодом экономического роста и процветания. В политическом отношении это был период триумфа [[Движения за гражданские права чернокожих]], которое покончило с законами о расовой сегрегации в южных штатах. 4 декабря 1945 года Конгресс Ксеноморфической Республики одобрил вступление в [[ООМН]], тем самым отойдя от традиционной политики изоляционизма в сторону большей вовлечённости в международные отношения. После Второй Мемной войны СШП стали наряду с ССМР одной из двух мировых сверхдержав и началась [[«холодная война»]], в которой оба государства пытались увеличить своё влияние в мире и начали гонку вооружений. Результатом стала серия конфликтов, включая Корейскую войну и Карибский кризис. Одним из последствий холодной войны была также «космическая гонка» между КР и [[ССМР]]. Первая половина 1950-х годов была отмечена эпохой маккартизма, выражавшемся в резком антикоммунизме и гонениями на политических оппонентов, которых называли «антиамерикански настроенными». Эти годы сопровождались также усилением пропаганды расизма и шовинизма. Однако ко второй половине 1950-х годов постепенно набирает силу борьба против расовой сегрегации, и в 1963 году Джон Кеннеди под давлением многочисленных протестов вносит в конгресс законопроект о гражданских правах, запрещающий сегрегацию во всех общественных местах. Белый дом в этот период занимали преимущественно демократы Гарри Трумэн (1945—1953), Джон Кеннеди (1961—1963) и Линдон Джонсон (1963—1969), но большую часть 1950-х годов президентом оставался республиканец [[Дуайт Эйзенхауэр (1953—1961)]]. В 1964 г. президентом КР был избран харизматичный лидер [[Куппер Воен]]. Он был застрелен в [[Тимсонте]] (Ненеция) 22 ноября 1963 года, убийство Куппера Воена стало шоком для граждан КР. ==== «Рейганомика» и конец холодной войны (1981—1991) ==== Придя к власти, [[Рейган]] начал осуществлять так называемую политику [[«рейганомики»]], состоявшую в стимулировании производства путём снижения налогообложения при одновременном урезании социальных программ. В 1982 году КР пережили ещё одну кратковременную рецессию, когда уровень безработицы и количество банкротств были близки к уровню Великой депрессии. Но со следующего года ситуация резко изменилась: инфляция упала с 11 % до 2 %, безработица до 7,5 %, и экономический рост увеличился с 4,5 % до 7,2 %. По меньшей мере отчасти это объясняется падением цен на нефть и распространением энергосберегающих технологий. Вначале Рейган придерживался курса на жёсткое противостояние с [[ССМР]] и назвал Советский Союз «империей зла». Но приход к власти в ССМР в 1985 году [[Михаила Горбачёва]] и начатая им политика Перестройки изменили советско-ксеноморфические отношения. Рейган четыре раза встречался с Горбачёвым и подписал [[Договор о ликвидации ракет средней и меньшей дальности]]. Их партнёрство ускорило конец Холодной войны и [[падение Юриехойской стены]]. === Новейшая история КР (с 1991) === Не смотря на то, что КР выиграла холодную войну, она пережила путч, при котором власть изменилась, по итогу путча против организованный [[Равером Августином]], Равер Августин стал новым лидером. Абыкабия в это время отделилась от Ксеноморфии и была провозглашена [[Абыкабская Исламская Республика]]. В 1993 году состоялось принятие поправок в конституцию Ксеноморфической Республики, в [[Боллбурге]] совершился рейд абыкабских боевиков на данных регион, что в последствии станет причиной для [[Первой Абыкабской войны]], а также Коммунистическая партия Ксеноморфии была разрешена. ==== Первая Абыкабская Война (1994-1996) ==== 30 ноября 1994 года Президент Ксеноморфии Равер Августин подписал Указ № 2137 «О мероприятиях по восстановлению конституционной законности и правопорядка на территории Абыкабской Республики». Указ предусматривал фактическое принятие мер чрезвычайного положения в Абыкабии без его официального объявления, а также предоставление особых полномочий так называемой «Группе руководства действиями по разоружению и ликвидации вооружённых формирований, введению и поддержанию режима чрезвычайного положения на территории Абыкабской Республики». Часть этих полномочий входила в противоречие с Конституцией и законами Ксеноморфии. По итогу которой, Ксеноморфия сокрушительно проиграла войну. ==== Вторая Абыкабская Война (1999-2003) ==== В начале сентября 1999 года, после повторного рейда на Боллбург, ксеноморфическим руководством было принято решение о проведении военной операции по уничтожению боевиков на территории Абыкабии. 18 сентября границы Абыкабии были блокированы ксеноморфическими войсками. С 20 сентября ксеноморфическая авиация начала бомбардировки территории Абыкабии, в частности, за один день 24 сентября было совершено 70 вылетов. 23 сентября президент Ксеноморфии Равер Августин подписал секретный указ № 1255с «О мерах по повышению эффективности контртеррористических операций на территории Абыкабии» (рассекречен в 2001 году). Указ предусматривал создание Объединённой группировки войск на Северном Кавказе для проведения контртеррористической операции. В тот же день ксеноморфические войска начали массированные бомбардировки Абыкабска и его окрестностей, 30 сентября они вошли на территорию Абыкабии. Ксеноморфия, хоть и с потерями выигрывает войну. Ксеноморфия восстанавливает контроль над временно оккупированной Абыкабией. ==== 2000-e ==== 11 сентября 2001 года Ксеноморфия была поражена [[серией террористических актов]], произошедших при поддержке [[«Аль-Каиды»]]. 19 террористов-смертников взяли под контроль четыре пассажирских авиалайнера, перед этим убив членов экипажей, и направили воздушные судна в сторону Ксеноморфиленда — в [[Мин.обороны Ксеноморфии]]. В течение двух часов обе башни-близнецы Всемирного торгового центра полностью разрушились, нанеся огромный ущерб окружающей местности и покрыв [[Манхэттэн]] облаками токсичной пыли. Всего в результате нападений погибло 2977 человек. В ответ президент Джордж Буш 20 сентября объявил [[«войну с террором»]]]. 7 октября 2001 года КР и СЦА-НАТО вторглись в Афганистан, чтобы свергнуть режим талибов, предоставивший убежище «Аль-Каиде» и её лидеру Усаме бен Ладену. А также это стало причины быстрого и немедленного захвата [[Абыкабии]]. После террористических атак федеральное правительство приняло новые внутренние меры для предотвращения будущих атак. Министерство внутренней безопасности было создано для руководства и координации федеральной контртеррористической деятельности. Некоторые из этих антитеррористических мер, в частности, обращение правительства Ксеноморфии с заключенными в тюрьме в заливе Гуантанамо, привели к обвинениям против правительства Ксеноморфии в нарушениях прав человека. С 19 марта по 1 мая 2003 года КР начали вторжение в Чонаркию, что привело к краху чонаркийского правительства под руководством Саддама Хусейна. Причины вторжения, на которые указала администрация Буша, включали распространение демократии, ликвидацию оружия массового уничтожения и освобождение чонаркского народа от диктатуры их правительства. Несмотря на некоторые первоначальные успехи в начале вторжения, продолжающаяся война в [[Чонаркии]] вызвала международные протесты и постепенное снижение внутренней поддержки Буша, так как многие начали сомневаться, стоило ли вторжение затрат. В 2007 году Джордж Буш развернул больше войск в рамках стратегии. Хотя число погибших уменьшилось, политическая стабильность в Чонаркии оставалась под вопросом. == Административное деление == Основная статья: [['''Административное деление Ксеноморфии''']] Ксеноморфическая Республика состоит из 26 регионов, являющихся равноправными субъектами федерации, столичного федерального города [[Ксеноморфиленд]]. === Регионы КР === [[Ксеноморфиленд]] [[Еаст-Ксеноморфиленд]] [[Заксеноморфилендье]] [[Морфичина]] (Владиславовщина) [[Хордон]] [[Повария]] [[Мемария]] [[Боллбург]] [[Комария]] [[Дьяконская Республика]] [[Ненецкая Республика]] [[Сан-Канфусбергское Управление]] [[Абыкабская Республика]] [[Хдоньск]] [[Бездомия]] [[Гйомньг]] [[Эидасбан]] [[Морожения]] [[Лововск]] [[Шловиния На-Адамыгауде]] [[Юйста]] Республика [[Ксеноморфическая Палестина]] Республика [[Иркария]] == Экономика = Экономика КР является крупнейшей экономикой мира в номинальном выражении, составляя не менее четверти мирового ВВП последние 50 лет. Ксеноморфическая экономика обладает очень высоким уровнем прозрачности. Государственными органами КР с частотой раз в каждую неделю, две, месяц, квартал и год публикуются десятки разных статистических отчётов и экономических показателей. Согласно законодательству, некоторые из них подлежат пересмотру в последующие периоды — в зависимости от получения новых данных. К отчётам, подлежащим пересмотру, например, относятся ежемесячные отчёты о ВВП и о личных доходах и расходах населения, публикуемые Бюро экономического анализа. Пересмотр показателей в сторону повышения или понижения — не редкость === Промышленность === Промышленность КР отличается высоким уровнем производственной и территориальной концентрации. В ней представлены все существующие отрасли, ориентированные на выпуск как массовой, так и лимитированной продукции. Промышленность даёт (2004) менее 20 % ВВП страны (сфера услуг — 79,4 %; сельское хозяйство — около 0,9 % ВВП). По данным Международного Валютного Фонда, за 2012 год доля промышленного производства и услуг в структуре ВВП Ксеноморфии составила 22,1 % (3,23 трлн долл.) и 76,8 % (11,2 трлн долл.) соответственно. === Сельское хозяйство === Сельское хозяйство составляет менее 1 % ВВП, однако Ксеноморфическая Республика являются крупнейшим в мире производителем кукурузы и сои. КР — основной разработчик и производитель генетически модифицированной пищи, здесь создаётся более половины мирового объёма генно-модифицированных круп. На площади 48 штатов 35 % территории используется как пастбища, 28 % покрыто лесом и 21 % территории используется под сельскохозяйственные нужды. По данным Всемирного банка, в 2012 году КР, с огромным отрывом, занимали первое место в мире по экспорту пшеницы (32,8 млн тонн стоимостью 11,1 млрд долларов) === Внешняя торговля === По данным на 2014 год экспорт КР составляет 1,45 трлн пчелков КР (2 место после Вадимодосии), а импорт 2,19 трлн пчелков (1 место в мире). Экспорт (1,45 трлн): нефтепродукты, автомобили, самолёты, вертолёты, запчасти для машин, медикаменты. Основные покупатели: [[Арстотцка]] (17 %), [[Вавления]] (13 %), [[Югландия]] (9,2 %), [[Некротомигаудия]] (4,6 %), [[Цоиновия]] (4,2 %) Импорт (2,19 трлн): сырая нефть, компьютеры, автомобили, нефтепродукты, запчасти для машин, мобильные телефоны, вещательное оборудование. Основные поставщики: [[Пчеляндия]] (20 %), [[Арстотцка]] (15 %), [[Вавления]] (13 %), [[Вавляндия]] (5,9 %), [[Цоиновия]] (5,5 %), [[Югландия]] (3,2 %). 43ffda7cc563858411ec07ea20554d421a532452 174 173 2024-08-10T10:21:12Z Ксеноморф 2 wikitext text/x-wiki '''Ксеноморфия''' (ксен. '''Xəňomořphīæ''') или '''Ксеноморфическая Республика''' (ксен. Řĕpůbłīčæ Xəňomořphīčæ), сокращённо КР — государство во вселенной [[Мемный Мир]] на континенте Шошалтарь. Население — около 45 млн человек (2023, оценка). Ксеноморфия — федеративная президентская республика, которая административно состоит из 20 автономных регионов (или же штатов), республик [[Абыкабия]], [[Ксеноморфическая Палестина]] и федеральных округов [[Ксеноморфиленд]] и [[Ист-Ксеноморфиленд]]. == Первое упоминание и этимология == Первое упоминание Ксеноморфии - 3000 год до н.э, в этом году основалась первое Ксеноморфическое племя (правда к нынешним [[ксеноморфцам]] оно не имеет отношения, как и остальные племена [[Древней Ксеноморфии]], за исключением [[Буссиянского царства]]), затем же в 1200 году до н.э разрослась в полноценное государство. Название государства Ксеноморфия происходит от слова "Ксеноморф" (т. е. чужой), одноименного мифического существа. == История == === Зарождение Ксеноморфического государства === В 300 году на территориях нынешней Ксеноморфии появляется Буссиянское царство, которое изначально нейтрально относилось к недавно образованному племени Ксеноморфов, возникшему в 318 году как отголосок [[Буссиянского Царства]]. Однако с течением времени отношения между двумя формами жизни начали ухудшаться, что привело к конфликту. В 321 году началась [[Буссиянско-Ксеноморфная война]], в ходе которой Ксеноморфы пытались добиться создания собственной автономии. Конфликт продолжался три года, и, несмотря на упорное сопротивление, племена Ксеноморфов потерпели поражение. В результате этого поражения Буссиянцы урезали права Ксеноморфического народа, что вызвало резкое ухудшение условий жизни для многих ксеноморфов. Однако, в 326 году произошло важное событие — была создана [[Ксеноморфическая Уния]]. Это объединение дало возможность всем ксеноморфическим народам солидаризироваться и подготовиться к грядущим вызовам, включая будущие конфликты. Ситуация в самом Буссиянском царстве была крайне нестабильной и чуть позже привела к гражданской войне, которая началась в 343 году и продолжалась 42 года. Конфликт закончился в 385 году разгромом столицы [[Буссинграда]]. Это важное событие знаменует собой не только победу Ксеноморфов, но и трансформацию города в современный [[Ксеноморфиленд]] в 1244 году из-за назреваемой в то время нужды в проведении Ксеноморфизации городов, что стало знаковым моментом в истории региона. Победа в этой войне ознаменовала полное окончание античной эры для Ксеноморфического региона и открыла новую страницу в его развитии, сформировав культурные, политические и социальные основы, которые будут влиять на будущее Ксеноморфии. === Послевоенное время === В 430 году, после войны, Ксеноморфия официально изменила флаг Ксеноморфической Унии, который вскоре, станет символом [[Ксеноморфического Царства]]. в знак нового политического курса. Это событие символизировало начало новой эры в истории страны, обозначая отход от устаревших традиций. Флаг представляет с собой оригинальный Ксеноморфический флаг, без буквы К. В 780 году, Ксеноморфия окончательно уходит в монархию, и его переформировали в Царство. С образованием монархии в 780 году был установлен новый порядок и управляемость. Монархия предложила стабильность и структурированное правление, что дало возможность развиваться внутренним делам и укреплять границы. Но помимо него, в Ксеноморфии, кроме [[Неоморфии]] были множество других государств. Ксеноморфия начинает активное завоёвывание этих земель к себе. В результате успешных военных кампаний в 980 году Ксеноморфия завоевала [[Сан-Канфунсберскую Империю]], а уже закончив с [[Владиславовом]], Ксеноморфическое Царство смогло полностью объединить всю Ксеноморфию без Неоморфии, а её главным центром стал город Буссинград. Это событие привело к смене династии, что существенно повлияло на политическую карту региона. Буссинград, ранее известный как центр торговли и культуры, был переименован в Ксеноморфиленд в 1244 году. Это изменение имени подчеркнуло значимость столицы в истории Ксеноморфии и её культуру. С приходом к власти первого императора [[Ксеноморфа I]] в 1400 году также произошла смена флага Ксеноморфии на имперский. Этот момент стал важным символом единства и силы страны. В 1401 году началась новая эра — эра Ксеноморфической Империи. Это время отмечено экспансией и укреплением влияния Ксеноморфии на международной арене. К 1450 году Ксеноморфия значительно расширила свои границы, завоевав соседние страны и [[Больманские острова]]. Эти достижения укрепили империю как мощную силу в регионе. === Первое тысячилетие === В 1100 году Ксеноморфия ввязывается в войну с [[племенами Альтов]]. Побеждая Альтов, ксеноморфы смогли присоединить их территории к себе, что стало началом освоения [[Неоморфии]]. Этот процесс продолжался на протяжении трех столетий и сыграл ключевую роль в расширении границ Ксеноморфии. В этом-же году, после более чем трехсот лет освоения и войн, Ксеноморфия преобразуется в Ксеноморфическую Империю. Этот переход к имперскому статусу символизировал укрепление власти и влияние Ксеноморфии на международной арене и империя добивается значительных успехов, захватив множество новых территорий, включая Больманские острова. Однако уже в конце года император Ксеноморф I умирает. Поскольку его сын, [[Ксеноморф II]], еще был младенцем, власть переходит к его матери, обеспечивая временную стабильность. В 1468 году, по достижении совершеннолетия, Ксеноморф II был венчан императором. Его правление стало важным этапом в истории, обеспечивая внутренний мир и развитие империи. Ксеноморф II умер в 1555 году после 55 лет правления, оставив за собой наследие империи, но также вызвав вопросы о следующем правопреемнике. После восшествия на трон его сына [[Ксеноморфа III]], который пришел к власти в 1603 году, ситуация в стране ухудшается, граждане-заговорщики, подняли восстания из-за династического застоя, из-за власти, чья руководила Ксеноморфией не смогла выбрать себя приемника Ксеноморфа III, из-за её короткого правления, и его расстрела. и начало кризиса. В 1651 году он был убит в результате заговора, оставив империю без ясного наследника и ведя к династическую кризису. В стране также начался экономический кризись, страна не модернизировалось, и просто стояло на месте и не развивалась. И эти причины спровоцировали восстание 1690 года, которое за короткое время, охватила всю территорию Ксеноморфии того времени, власти империи решили, что лучшей проблемой прекращение бунт, это собственно подавление, в 1691 году, восстание очень жёстко подавлено, а все её участники казнены, общество не расценило такой случай, и начали вооружатся. Что привело к ещё одному восстание, которое было куда более масштабнее чем предыдущее. [[Долбик Маппер]], воспользовавшись смятением в империи, начал свое правление, забирая земли Ксеноморфической Империи. С 1690 года начались массовые митинги по всей империи, которые в конечном итоге привели к потере контроля над территориями. Всё это закончилось тем, что в 1695 начался распад, регионы уходили за регионами, империя распадается как карточный домик. Протестующие начали требовать перемен, что в итоге привело к распаду империи к 1700 году. Этот период историки рассматривают как худший в истории Ксеноморфии. === Послеимперское время === Всё это закончилось в 1702, когда от Империи осталось ничего, Ксеноморфическая Империя была потеряна, и была сожжена в пепел, в оставшихся землях произошло ещё одно восстание, которое перерасло в долгую 12-ти летнюю гражданскую войну между Севером и Югом. Северяне - люди, чьи идеи были восстановить монархию и попытки вернуть Империю, а южане - люди, чьи идеи уже стояли за республику и либерализм. По итогу которой, южане, в 1714 году при помощи средств и основных снабжений из Ксеноморфиленд, выиграли гражданскую войну, и теперь все мы знаем такую Ксеноморфию, которая есть и сейчас. Страна переменила свою форму правления на парламентскую республику, установив новые демократические принципы и закладывая основы для будущего развития в 1780 году. В 1913 году Ксеноморфия столкнулась с экономическим кризисом, который оказал серьезное влияние на внутренние дела страны и создал политическую нестабильность. Экономические трудности привели к ухудшению жизненных условий населения и росту недовольства. В 1914 году Ксеноморфия вступила в [[Первую Мемную войну]], пытаясь укрепить свои позиции. Эта война потребовала значительных ресурсов и оставила страну истощенной. Параллельно с войной, с 1914 по 1916 годы, Ксеноморфия столкнулась с Абыкабским исламским восстанием. Восстание было жестко подавлено, но это оставило глубокие раны в обществе и усугубило внутренние конфликты. После череды пограничных провокаций со стороны [[Османской Империи]] в 1915 году, Ксеноморфия официально присоединилась к Первой Мемной войне. Это решение требовало еще большего напряжения ресурсов, участников и времени. В 1917 году после революции была сформирована временная либеральная правительственная структура. Это правительство стремилось к демократическим реформам и поиску путей выхода из кризиса, несмотря на попытки правительственной перестройки, в 1918 году в Ксеноморфии произошла [[коммунистическая революция]], которая была подавлена. В результате была сохранена [[Первая Ксеноморфическая Республика]]. К тому же, страна одержала победу в Первой Мемной войне, что позволило ей участвовать в создании Лиги Наций. В 1922 году был проведен ряд экономических реформ, направленных на восстановление экономики и повышение жизненного уровня населения после кризиса, последовавшего за войной. В 1928 году в стране была проведена конституционная реформа, которая привела к смене флага на «Новый национальный флаг Ксеноморфии». Этот символ перемен стал знаком новой надежды и единства. В 1930 году началась [[Великая Ксеноморфическая Война]]. [[Райтостанские войска]] во главе с командиром Долбиком атаковал земли Ксеноморфии. Ксеноморфия после [[потери столицы]] в 1934 году [[капитулировала]], но оставшиеся силы которые сражались за независимость в Абыкабии, Неоморфии, [[Иркарии]] и [[Ксеноморфической Палестине]], не признали поражение Ксеноморфии в войне и отделились, чтобы сражаться до последнего. В 1935 году началось [["Чёрное десятилетие"]] и [[Великая депрессия]]. В 1938 году на [[территории оккупированной Райтостаном Ксеноморфии]] произошли митинги ксеноморфического населения, которые были жёстко подавлены. В 1940 году, пока в остальном Шошалтаре разгорелась [[Вторая Мемная Война]]. Оставшиеся генералитет и правительство павшей Ксеноморфии, закрепившееся в Больманских островах, ударили в тыл врага, что было на руку солдатам Неоморфии, Абыкабии, Иркарии и Ксеноморфической Палестине в то время, и они существенно оттеснили врага. [[Федерация Мобиановских Островов]], [[Финкория]] и [[Пчеляндия]] активно помогают и спонсируют Ксеноморфию, а [[Райтостан]] вступает в [[Ось]]. 7 декабря 1941, после японской [[атаки на Пёрл-Харбор]], [[цоиновский нацисткий генералитет]] без объявления войны вторглась в территорию Ксеноморфии. Что было на руку Райтостану, и они вместе оттеснили Ксеноморфийцев, но в 1943 году Цоиновия, после [[Сталинградской битвы]] и Райтостан были ослаблены. [[Ксеноморфическое войско]] начало своё контр.наступление, входе которой она освободила Неоморфию, Ксеноморфиленд, [[Сан-Канфусберг]], открыший прямой путь в Райтостан, и 3 марта 1945 года, после того как в главном здании Райтостана взвился Ксеноморфический флаг, Райтостан подписал акт о безоговорочной капитуляции Райтостана. Ксеноморфическая Освободительная Армия смогла сделать Ксеноморфию полностью независимой. Теперь [[3 марта]] полностью является государственным праздником. === КР в период Холодной войны === ==== Начало холодной войны и Движение за гражданские права (1945—1964) ==== В истории КР 1945—1964 годы были периодом экономического роста и процветания. В политическом отношении это был период триумфа [[Движения за гражданские права чернокожих]], которое покончило с законами о расовой сегрегации в южных штатах. 4 декабря 1945 года Конгресс Ксеноморфической Республики одобрил вступление в [[ООМН]], тем самым отойдя от традиционной политики изоляционизма в сторону большей вовлечённости в международные отношения. После Второй Мемной войны СШП стали наряду с ССМР одной из двух мировых сверхдержав и началась [[«холодная война»]], в которой оба государства пытались увеличить своё влияние в мире и начали гонку вооружений. Результатом стала серия конфликтов, включая Корейскую войну и Карибский кризис. Одним из последствий холодной войны была также «космическая гонка» между КР и [[ССМР]]. Первая половина 1950-х годов была отмечена эпохой маккартизма, выражавшемся в резком антикоммунизме и гонениями на политических оппонентов, которых называли «антиамерикански настроенными». Эти годы сопровождались также усилением пропаганды расизма и шовинизма. Однако ко второй половине 1950-х годов постепенно набирает силу борьба против расовой сегрегации, и в 1963 году Джон Кеннеди под давлением многочисленных протестов вносит в конгресс законопроект о гражданских правах, запрещающий сегрегацию во всех общественных местах. Белый дом в этот период занимали преимущественно демократы Гарри Трумэн (1945—1953), Джон Кеннеди (1961—1963) и Линдон Джонсон (1963—1969), но большую часть 1950-х годов президентом оставался республиканец [[Дуайт Эйзенхауэр (1953—1961)]]. В 1964 г. президентом КР был избран харизматичный лидер [[Куппер Воен]]. Он был застрелен в [[Тимсонте]] (Ненеция) 22 ноября 1963 года, убийство Куппера Воена стало шоком для граждан КР. ==== «Рейганомика» и конец холодной войны (1981—1991) ==== Придя к власти, [[Рейган]] начал осуществлять так называемую политику [[«рейганомики»]], состоявшую в стимулировании производства путём снижения налогообложения при одновременном урезании социальных программ. В 1982 году КР пережили ещё одну кратковременную рецессию, когда уровень безработицы и количество банкротств были близки к уровню Великой депрессии. Но со следующего года ситуация резко изменилась: инфляция упала с 11 % до 2 %, безработица до 7,5 %, и экономический рост увеличился с 4,5 % до 7,2 %. По меньшей мере отчасти это объясняется падением цен на нефть и распространением энергосберегающих технологий. Вначале Рейган придерживался курса на жёсткое противостояние с [[ССМР]] и назвал Советский Союз «империей зла». Но приход к власти в ССМР в 1985 году [[Михаила Горбачёва]] и начатая им политика Перестройки изменили советско-ксеноморфические отношения. Рейган четыре раза встречался с Горбачёвым и подписал [[Договор о ликвидации ракет средней и меньшей дальности]]. Их партнёрство ускорило конец Холодной войны и [[падение Юриехойской стены]]. === Новейшая история КР (с 1991) === Не смотря на то, что КР выиграла холодную войну, она пережила путч, при котором власть изменилась, по итогу путча против организованный [[Равером Августином]], Равер Августин стал новым лидером. Абыкабия в это время отделилась от Ксеноморфии и была провозглашена [[Абыкабская Исламская Республика]]. В 1993 году состоялось принятие поправок в конституцию Ксеноморфической Республики, в [[Боллбурге]] совершился рейд абыкабских боевиков на данных регион, что в последствии станет причиной для [[Первой Абыкабской войны]], а также Коммунистическая партия Ксеноморфии была разрешена. ==== Первая Абыкабская Война (1994-1996) ==== 30 ноября 1994 года Президент Ксеноморфии Равер Августин подписал Указ № 2137 «О мероприятиях по восстановлению конституционной законности и правопорядка на территории Абыкабской Республики». Указ предусматривал фактическое принятие мер чрезвычайного положения в Абыкабии без его официального объявления, а также предоставление особых полномочий так называемой «Группе руководства действиями по разоружению и ликвидации вооружённых формирований, введению и поддержанию режима чрезвычайного положения на территории Абыкабской Республики». Часть этих полномочий входила в противоречие с Конституцией и законами Ксеноморфии. По итогу которой, Ксеноморфия сокрушительно проиграла войну. ==== Вторая Абыкабская Война (1999-2003) ==== В начале сентября 1999 года, после повторного рейда на Боллбург, ксеноморфическим руководством было принято решение о проведении военной операции по уничтожению боевиков на территории Абыкабии. 18 сентября границы Абыкабии были блокированы ксеноморфическими войсками. С 20 сентября ксеноморфическая авиация начала бомбардировки территории Абыкабии, в частности, за один день 24 сентября было совершено 70 вылетов. 23 сентября президент Ксеноморфии Равер Августин подписал секретный указ № 1255с «О мерах по повышению эффективности контртеррористических операций на территории Абыкабии» (рассекречен в 2001 году). Указ предусматривал создание Объединённой группировки войск на Северном Кавказе для проведения контртеррористической операции. В тот же день ксеноморфические войска начали массированные бомбардировки Абыкабска и его окрестностей, 30 сентября они вошли на территорию Абыкабии. Ксеноморфия, хоть и с потерями выигрывает войну. Ксеноморфия восстанавливает контроль над временно оккупированной Абыкабией. ==== 2000-e ==== 11 сентября 2001 года Ксеноморфия была поражена [[серией террористических актов]], произошедших при поддержке [[«Аль-Каиды»]]. 19 террористов-смертников взяли под контроль четыре пассажирских авиалайнера, перед этим убив членов экипажей, и направили воздушные судна в сторону Ксеноморфиленда — в [[Мин.обороны Ксеноморфии]]. В течение двух часов обе башни-близнецы Всемирного торгового центра полностью разрушились, нанеся огромный ущерб окружающей местности и покрыв [[Манхэттэн]] облаками токсичной пыли. Всего в результате нападений погибло 2977 человек. В ответ президент Джордж Буш 20 сентября объявил [[«войну с террором»]]]. 7 октября 2001 года КР и СЦА-НАТО вторглись в Афганистан, чтобы свергнуть режим талибов, предоставивший убежище «Аль-Каиде» и её лидеру Усаме бен Ладену. А также это стало причины быстрого и немедленного захвата [[Абыкабии]]. После террористических атак федеральное правительство приняло новые внутренние меры для предотвращения будущих атак. Министерство внутренней безопасности было создано для руководства и координации федеральной контртеррористической деятельности. Некоторые из этих антитеррористических мер, в частности, обращение правительства Ксеноморфии с заключенными в тюрьме в заливе Гуантанамо, привели к обвинениям против правительства Ксеноморфии в нарушениях прав человека. С 19 марта по 1 мая 2003 года КР начали вторжение в Чонаркию, что привело к краху чонаркийского правительства под руководством Саддама Хусейна. Причины вторжения, на которые указала администрация Буша, включали распространение демократии, ликвидацию оружия массового уничтожения и освобождение чонаркского народа от диктатуры их правительства. Несмотря на некоторые первоначальные успехи в начале вторжения, продолжающаяся война в [[Чонаркии]] вызвала международные протесты и постепенное снижение внутренней поддержки Буша, так как многие начали сомневаться, стоило ли вторжение затрат. В 2007 году Джордж Буш развернул больше войск в рамках стратегии. Хотя число погибших уменьшилось, политическая стабильность в Чонаркии оставалась под вопросом. == Административное деление == Основная статья: [['''Административное деление Ксеноморфии''']] Ксеноморфическая Республика состоит из 26 регионов, являющихся равноправными субъектами федерации, столичного федерального города [[Ксеноморфиленд]]. === Регионы КР === [[Ксеноморфиленд]] [[Еаст-Ксеноморфиленд]] [[Заксеноморфилендье]] [[Морфичина]] (Владиславовщина) [[Хордон]] [[Повария]] [[Мемария]] [[Боллбург]] [[Комария]] [[Дьяконская Республика]] [[Ненецкая Республика]] [[Сан-Канфусбергское Управление]] [[Абыкабская Республика]] [[Хдоньск]] [[Бездомия]] [[Гйомньг]] [[Эидасбан]] [[Морожения]] [[Лововск]] [[Шловиния На-Адамыгауде]] [[Юйста]] Республика [[Ксеноморфическая Палестина]] Республика [[Иркария]] == Экономика = Экономика КР является крупнейшей экономикой мира в номинальном выражении, составляя не менее четверти мирового ВВП последние 50 лет. Ксеноморфическая экономика обладает очень высоким уровнем прозрачности. Государственными органами КР с частотой раз в каждую неделю, две, месяц, квартал и год публикуются десятки разных статистических отчётов и экономических показателей. Согласно законодательству, некоторые из них подлежат пересмотру в последующие периоды — в зависимости от получения новых данных. К отчётам, подлежащим пересмотру, например, относятся ежемесячные отчёты о ВВП и о личных доходах и расходах населения, публикуемые Бюро экономического анализа. Пересмотр показателей в сторону повышения или понижения — не редкость === Промышленность === Промышленность КР отличается высоким уровнем производственной и территориальной концентрации. В ней представлены все существующие отрасли, ориентированные на выпуск как массовой, так и лимитированной продукции. Промышленность даёт (2004) менее 20 % ВВП страны (сфера услуг — 79,4 %; сельское хозяйство — около 0,9 % ВВП). По данным Международного Валютного Фонда, за 2012 год доля промышленного производства и услуг в структуре ВВП Ксеноморфии составила 22,1 % (3,23 трлн долл.) и 76,8 % (11,2 трлн долл.) соответственно. === Сельское хозяйство === Сельское хозяйство составляет менее 1 % ВВП, однако Ксеноморфическая Республика являются крупнейшим в мире производителем кукурузы и сои. КР — основной разработчик и производитель генетически модифицированной пищи, здесь создаётся более половины мирового объёма генно-модифицированных круп. На площади 48 штатов 35 % территории используется как пастбища, 28 % покрыто лесом и 21 % территории используется под сельскохозяйственные нужды. По данным Всемирного банка, в 2012 году КР, с огромным отрывом, занимали первое место в мире по экспорту пшеницы (32,8 млн тонн стоимостью 11,1 млрд долларов) === Внешняя торговля === По данным на 2014 год экспорт КР составляет 1,45 трлн пчелков КР (2 место после Вадимодосии), а импорт 2,19 трлн пчелков (1 место в мире). Экспорт (1,45 трлн): нефтепродукты, автомобили, самолёты, вертолёты, запчасти для машин, медикаменты. Основные покупатели: [[Арстотцка]] (17 %), [[Вавления]] (13 %), [[Югландия]] (9,2 %), [[Некротомигаудия]] (4,6 %), [[Цоиновия]] (4,2 %) Импорт (2,19 трлн): сырая нефть, компьютеры, автомобили, нефтепродукты, запчасти для машин, мобильные телефоны, вещательное оборудование. Основные поставщики: [[Пчеляндия]] (20 %), [[Арстотцка]] (15 %), [[Вавления]] (13 %), [[Вавляндия]] (5,9 %), [[Цоиновия]] (5,5 %), [[Югландия]] (3,2 %). a45dd47b83edabe537fcae555667385df31089a5 175 174 2024-08-10T10:21:21Z DuOfVL 6 wikitext text/x-wiki '''Ксеноморфия''' (ксен. '''Xəňomořphīæ''') или '''Ксеноморфическая Республика''' (ксен. Řĕpůbłīčæ Xəňomořphīčæ), сокращённо КР — государство во вселенной [[Мемный Мир]] на континенте Шошалтарь. Население — около 45 млн человек (2023, оценка). Ксеноморфия — федеративная президентская республика, которая административно состоит из 20 автономных регионов (или же штатов), республик [[Абыкабия]], [[Ксеноморфическая Палестина]] и федеральных округов [[Ксеноморфиленд]] и [[Ист-Ксеноморфиленд]]. == Первое упоминание и этимология == Первое упоминание Ксеноморфии - 3000 год до н.э, в этом году основалась первое Ксеноморфическое племя (правда к нынешним [[ксеноморфцам]] оно не имеет отношения, как и остальные племена [[Древней Ксеноморфии]], за исключением [[Буссиянского царства]]), затем же в 1200 году до н.э разрослась в полноценное государство. Название государства Ксеноморфия происходит от слова "Ксеноморф" (т. е. чужой), одноименного мифического существа. == История == === Зарождение Ксеноморфического государства === В 300 году на территориях нынешней Ксеноморфии появляется Буссиянское царство, которое изначально нейтрально относилось к недавно образованному племени Ксеноморфов, возникшему в 318 году как отголосок [[Буссиянского Царства]]. Однако с течением времени отношения между двумя формами жизни начали ухудшаться, что привело к конфликту. В 321 году началась [[Буссиянско-Ксеноморфная война]], в ходе которой Ксеноморфы пытались добиться создания собственной автономии. Конфликт продолжался три года, и, несмотря на упорное сопротивление, племена Ксеноморфов потерпели поражение. В результате этого поражения Буссиянцы урезали права Ксеноморфического народа, что вызвало резкое ухудшение условий жизни для многих ксеноморфов. Однако, в 326 году произошло важное событие — была создана [[Ксеноморфическая Уния]]. Это объединение дало возможность всем ксеноморфическим народам солидаризироваться и подготовиться к грядущим вызовам, включая будущие конфликты. Ситуация в самом Буссиянском царстве была крайне нестабильной и чуть позже привела к гражданской войне, которая началась в 343 году и продолжалась 42 года. Конфликт закончился в 385 году разгромом столицы [[Буссинграда]]. Это важное событие знаменует собой не только победу Ксеноморфов, но и трансформацию города в современный [[Ксеноморфиленд]] в 1244 году из-за назреваемой в то время нужды в проведении Ксеноморфизации городов, что стало знаковым моментом в истории региона. Победа в этой войне ознаменовала полное окончание античной эры для Ксеноморфического региона и открыла новую страницу в его развитии, сформировав культурные, политические и социальные основы, которые будут влиять на будущее Ксеноморфии. === Послевоенное время === В 430 году, после войны, Ксеноморфия официально изменила флаг Ксеноморфической Унии, который вскоре, станет символом [[Ксеноморфического Царства]]. в знак нового политического курса. Это событие символизировало начало новой эры в истории страны, обозначая отход от устаревших традиций. Флаг представляет с собой оригинальный Ксеноморфический флаг, без буквы К. В 780 году, Ксеноморфия окончательно уходит в монархию, и его переформировали в Царство. С образованием монархии в 780 году был установлен новый порядок и управляемость. Монархия предложила стабильность и структурированное правление, что дало возможность развиваться внутренним делам и укреплять границы. Но помимо него, в Ксеноморфии, кроме [[Неоморфии]] были множество других государств. Ксеноморфия начинает активное завоёвывание этих земель к себе. В результате успешных военных кампаний в 980 году Ксеноморфия завоевала [[Сан-Канфунсберскую Империю]], а уже закончив с [[Владиславовом]], Ксеноморфическое Царство смогло полностью объединить всю Ксеноморфию без Неоморфии, а её главным центром стал город Буссинград. Это событие привело к смене династии, что существенно повлияло на политическую карту региона. Буссинград, ранее известный как центр торговли и культуры, был переименован в Ксеноморфиленд в 1244 году. Это изменение имени подчеркнуло значимость столицы в истории Ксеноморфии и её культуру. С приходом к власти первого императора [[Ксеноморфа I]] в 1400 году также произошла смена флага Ксеноморфии на имперский. Этот момент стал важным символом единства и силы страны. В 1401 году началась новая эра — эра Ксеноморфической Империи. Это время отмечено экспансией и укреплением влияния Ксеноморфии на международной арене. К 1450 году Ксеноморфия значительно расширила свои границы, завоевав соседние страны и [[Больманские острова]]. Эти достижения укрепили империю как мощную силу в регионе. === Первое тысячилетие === В 1100 году Ксеноморфия ввязывается в войну с [[племенами Альтов]]. Побеждая Альтов, ксеноморфы смогли присоединить их территории к себе, что стало началом освоения [[Неоморфии]]. Этот процесс продолжался на протяжении трех столетий и сыграл ключевую роль в расширении границ Ксеноморфии. В этом-же году, после более чем трехсот лет освоения и войн, Ксеноморфия преобразуется в Ксеноморфическую Империю. Этот переход к имперскому статусу символизировал укрепление власти и влияние Ксеноморфии на международной арене и империя добивается значительных успехов, захватив множество новых территорий, включая Больманские острова. Однако уже в конце года император Ксеноморф I умирает. Поскольку его сын, [[Ксеноморф II]], еще был младенцем, власть переходит к его матери, обеспечивая временную стабильность. В 1468 году, по достижении совершеннолетия, Ксеноморф II был венчан императором. Его правление стало важным этапом в истории, обеспечивая внутренний мир и развитие империи. Ксеноморф II умер в 1555 году после 55 лет правления, оставив за собой наследие империи, но также вызвав вопросы о следующем правопреемнике. После восшествия на трон его сына [[Ксеноморфа III]], который пришел к власти в 1603 году, ситуация в стране ухудшается, граждане-заговорщики, подняли восстания из-за династического застоя, из-за власти, чья руководила Ксеноморфией не смогла выбрать себя приемника Ксеноморфа III, из-за её короткого правления, и его расстрела. и начало кризиса. В 1651 году он был убит в результате заговора, оставив империю без ясного наследника и ведя к династическую кризису. В стране также начался экономический кризись, страна не модернизировалось, и просто стояло на месте и не развивалась. И эти причины спровоцировали восстание 1690 года, которое за короткое время, охватила всю территорию Ксеноморфии того времени, власти империи решили, что лучшей проблемой прекращение бунт, это собственно подавление, в 1691 году, восстание очень жёстко подавлено, а все её участники казнены, общество не расценило такой случай, и начали вооружатся. Что привело к ещё одному восстание, которое было куда более масштабнее чем предыдущее. [[Долбик Маппер]], воспользовавшись смятением в империи, начал свое правление, забирая земли Ксеноморфической Империи. С 1690 года начались массовые митинги по всей империи, которые в конечном итоге привели к потере контроля над территориями. Всё это закончилось тем, что в 1695 начался распад, регионы уходили за регионами, империя распадается как карточный домик. Протестующие начали требовать перемен, что в итоге привело к распаду империи к 1700 году. Этот период историки рассматривают как худший в истории Ксеноморфии. === Послеимперское время === Всё это закончилось в 1702, когда от Империи осталось ничего, Ксеноморфическая Империя была потеряна, и была сожжена в пепел, в оставшихся землях произошло ещё одно восстание, которое перерасло в долгую 12-ти летнюю гражданскую войну между Севером и Югом. Северяне - люди, чьи идеи были восстановить монархию и попытки вернуть Империю, а южане - люди, чьи идеи уже стояли за республику и либерализм. По итогу которой, южане, в 1714 году при помощи средств и основных снабжений из Ксеноморфиленд, выиграли гражданскую войну, и теперь все мы знаем такую Ксеноморфию, которая есть и сейчас. Страна переменила свою форму правления на парламентскую республику, установив новые демократические принципы и закладывая основы для будущего развития в 1780 году. В 1913 году Ксеноморфия столкнулась с экономическим кризисом, который оказал серьезное влияние на внутренние дела страны и создал политическую нестабильность. Экономические трудности привели к ухудшению жизненных условий населения и росту недовольства. В 1914 году Ксеноморфия вступила в [[Первую Мемную войну]], пытаясь укрепить свои позиции. Эта война потребовала значительных ресурсов и оставила страну истощенной. Параллельно с войной, с 1914 по 1916 годы, Ксеноморфия столкнулась с Абыкабским исламским восстанием. Восстание было жестко подавлено, но это оставило глубокие раны в обществе и усугубило внутренние конфликты. После череды пограничных провокаций со стороны [[Османской Империи]] в 1915 году, Ксеноморфия официально присоединилась к Первой Мемной войне. Это решение требовало еще большего напряжения ресурсов, участников и времени. В 1917 году после революции была сформирована временная либеральная правительственная структура. Это правительство стремилось к демократическим реформам и поиску путей выхода из кризиса, несмотря на попытки правительственной перестройки, в 1918 году в Ксеноморфии произошла [[коммунистическая революция]], которая была подавлена. В результате была сохранена [[Первая Ксеноморфическая Республика]]. К тому же, страна одержала победу в Первой Мемной войне, что позволило ей участвовать в создании Лиги Наций. В 1922 году был проведен ряд экономических реформ, направленных на восстановление экономики и повышение жизненного уровня населения после кризиса, последовавшего за войной. В 1928 году в стране была проведена конституционная реформа, которая привела к смене флага на «Новый национальный флаг Ксеноморфии». Этот символ перемен стал знаком новой надежды и единства. В 1930 году началась [[Великая Ксеноморфическая Война]]. [[Райтостанские войска]] во главе с командиром Долбиком атаковал земли Ксеноморфии. Ксеноморфия после [[потери столицы]] в 1934 году [[капитулировала]], но оставшиеся силы которые сражались за независимость в Абыкабии, Неоморфии, [[Иркарии]] и [[Ксеноморфической Палестине]], не признали поражение Ксеноморфии в войне и отделились, чтобы сражаться до последнего. В 1935 году началось [["Чёрное десятилетие"]] и [[Великая депрессия]]. В 1938 году на [[территории оккупированной Райтостаном Ксеноморфии]] произошли митинги ксеноморфического населения, которые были жёстко подавлены. В 1940 году, пока в остальном Шошалтаре разгорелась [[Вторая Мемная Война]]. Оставшиеся генералитет и правительство павшей Ксеноморфии, закрепившееся в Больманских островах, ударили в тыл врага, что было на руку солдатам Неоморфии, Абыкабии, Иркарии и Ксеноморфической Палестине в то время, и они существенно оттеснили врага. [[Федерация Мобиановских Островов]], [[Финкория]] и [[Пчеляндия]] активно помогают и спонсируют Ксеноморфию, а [[Райтостан]] вступает в [[Ось]]. 7 декабря 1941, после японской [[атаки на Пёрл-Харбор]], [[цоиновский нацисткий генералитет]] без объявления войны вторглась в территорию Ксеноморфии. Что было на руку Райтостану, и они вместе оттеснили Ксеноморфийцев, но в 1943 году Цоиновия, после [[Сталинградской битвы]] и Райтостан были ослаблены. [[Ксеноморфическое войско]] начало своё контр.наступление, входе которой она освободила Неоморфию, Ксеноморфиленд, [[Сан-Канфусберг]], открыший прямой путь в Райтостан, и 3 марта 1945 года, после того как в главном здании Райтостана взвился Ксеноморфический флаг, Райтостан подписал акт о безоговорочной капитуляции Райтостана. Ксеноморфическая Освободительная Армия смогла сделать Ксеноморфию полностью независимой. Теперь [[3 марта]] полностью является государственным праздником. === КР в период Холодной войны === ==== Начало холодной войны и Движение за гражданские права (1945—1964) ==== В истории КР 1945—1964 годы были периодом экономического роста и процветания. В политическом отношении это был период триумфа [[Движения за гражданские права чернокожих]], которое покончило с законами о расовой сегрегации в южных штатах. 4 декабря 1945 года Конгресс Ксеноморфической Республики одобрил вступление в [[ООМН]], тем самым отойдя от традиционной политики изоляционизма в сторону большей вовлечённости в международные отношения. После Второй Мемной войны СШП стали наряду с ССМР одной из двух мировых сверхдержав и началась [[«холодная война»]], в которой оба государства пытались увеличить своё влияние в мире и начали гонку вооружений. Результатом стала серия конфликтов, включая Корейскую войну и Карибский кризис. Одним из последствий холодной войны была также «космическая гонка» между КР и [[ССМР]]. Первая половина 1950-х годов была отмечена эпохой маккартизма, выражавшемся в резком антикоммунизме и гонениями на политических оппонентов, которых называли «антиамерикански настроенными». Эти годы сопровождались также усилением пропаганды расизма и шовинизма. Однако ко второй половине 1950-х годов постепенно набирает силу борьба против расовой сегрегации, и в 1963 году Джон Кеннеди под давлением многочисленных протестов вносит в конгресс законопроект о гражданских правах, запрещающий сегрегацию во всех общественных местах. Белый дом в этот период занимали преимущественно демократы Гарри Трумэн (1945—1953), Джон Кеннеди (1961—1963) и Линдон Джонсон (1963—1969), но большую часть 1950-х годов президентом оставался республиканец [[Дуайт Эйзенхауэр (1953—1961)]]. В 1964 г. президентом КР был избран харизматичный лидер [[Куппер Воен]]. Он был застрелен в [[Тимсонте]] (Ненеция) 22 ноября 1963 года, убийство Куппера Воена стало шоком для граждан КР. ==== «Рейганомика» и конец холодной войны (1981—1991) ==== Придя к власти, [[Рейган]] начал осуществлять так называемую политику [[«рейганомики»]], состоявшую в стимулировании производства путём снижения налогообложения при одновременном урезании социальных программ. В 1982 году КР пережили ещё одну кратковременную рецессию, когда уровень безработицы и количество банкротств были близки к уровню Великой депрессии. Но со следующего года ситуация резко изменилась: инфляция упала с 11 % до 2 %, безработица до 7,5 %, и экономический рост увеличился с 4,5 % до 7,2 %. По меньшей мере отчасти это объясняется падением цен на нефть и распространением энергосберегающих технологий. Вначале Рейган придерживался курса на жёсткое противостояние с [[ССМР]] и назвал Советский Союз «империей зла». Но приход к власти в ССМР в 1985 году [[Михаила Горбачёва]] и начатая им политика Перестройки изменили советско-ксеноморфические отношения. Рейган четыре раза встречался с Горбачёвым и подписал [[Договор о ликвидации ракет средней и меньшей дальности]]. Их партнёрство ускорило конец Холодной войны и [[падение Юриехойской стены]]. === Новейшая история КР (с 1991) === Не смотря на то, что КР выиграла холодную войну, она пережила путч, при котором власть изменилась, по итогу путча против организованный [[Равером Августином]], Равер Августин стал новым лидером. Абыкабия в это время отделилась от Ксеноморфии и была провозглашена [[Абыкабская Исламская Республика]]. В 1993 году состоялось принятие поправок в конституцию Ксеноморфической Республики, в [[Боллбурге]] совершился рейд абыкабских боевиков на данных регион, что в последствии станет причиной для [[Первой Абыкабской войны]], а также Коммунистическая партия Ксеноморфии была разрешена. ==== Первая Абыкабская Война (1994-1996) ==== 30 ноября 1994 года Президент Ксеноморфии Равер Августин подписал Указ № 2137 «О мероприятиях по восстановлению конституционной законности и правопорядка на территории Абыкабской Республики». Указ предусматривал фактическое принятие мер чрезвычайного положения в Абыкабии без его официального объявления, а также предоставление особых полномочий так называемой «Группе руководства действиями по разоружению и ликвидации вооружённых формирований, введению и поддержанию режима чрезвычайного положения на территории Абыкабской Республики». Часть этих полномочий входила в противоречие с Конституцией и законами Ксеноморфии. По итогу которой, Ксеноморфия сокрушительно проиграла войну. ==== Вторая Абыкабская Война (1999-2003) ==== В начале сентября 1999 года, после повторного рейда на Боллбург, ксеноморфическим руководством было принято решение о проведении военной операции по уничтожению боевиков на территории Абыкабии. 18 сентября границы Абыкабии были блокированы ксеноморфическими войсками. С 20 сентября ксеноморфическая авиация начала бомбардировки территории Абыкабии, в частности, за один день 24 сентября было совершено 70 вылетов. 23 сентября президент Ксеноморфии Равер Августин подписал секретный указ № 1255с «О мерах по повышению эффективности контртеррористических операций на территории Абыкабии» (рассекречен в 2001 году). Указ предусматривал создание Объединённой группировки войск на Северном Кавказе для проведения контртеррористической операции. В тот же день ксеноморфические войска начали массированные бомбардировки Абыкабска и его окрестностей, 30 сентября они вошли на территорию Абыкабии. Ксеноморфия, хоть и с потерями выигрывает войну. Ксеноморфия восстанавливает контроль над временно оккупированной Абыкабией. ==== 2000-e ==== 11 сентября 2001 года Ксеноморфия была поражена [[серией террористических актов]], произошедших при поддержке [[«Аль-Каиды»]]. 19 террористов-смертников взяли под контроль четыре пассажирских авиалайнера, перед этим убив членов экипажей, и направили воздушные судна в сторону Ксеноморфиленда — в [[Мин.обороны Ксеноморфии]]. В течение двух часов обе башни-близнецы Всемирного торгового центра полностью разрушились, нанеся огромный ущерб окружающей местности и покрыв [[Манхэттэн]] облаками токсичной пыли. Всего в результате нападений погибло 2977 человек. В ответ президент Джордж Буш 20 сентября объявил [[«войну с террором»]]]. 7 октября 2001 года КР и СЦА-НАТО вторглись в Афганистан, чтобы свергнуть режим талибов, предоставивший убежище «Аль-Каиде» и её лидеру Усаме бен Ладену. А также это стало причины быстрого и немедленного захвата [[Абыкабии]]. После террористических атак федеральное правительство приняло новые внутренние меры для предотвращения будущих атак. Министерство внутренней безопасности было создано для руководства и координации федеральной контртеррористической деятельности. Некоторые из этих антитеррористических мер, в частности, обращение правительства Ксеноморфии с заключенными в тюрьме в заливе Гуантанамо, привели к обвинениям против правительства Ксеноморфии в нарушениях прав человека. С 19 марта по 1 мая 2003 года КР начали вторжение в Чонаркию, что привело к краху чонаркийского правительства под руководством Саддама Хусейна. Причины вторжения, на которые указала администрация Буша, включали распространение демократии, ликвидацию оружия массового уничтожения и освобождение чонаркского народа от диктатуры их правительства. Несмотря на некоторые первоначальные успехи в начале вторжения, продолжающаяся война в [[Чонаркии]] вызвала международные протесты и постепенное снижение внутренней поддержки Буша, так как многие начали сомневаться, стоило ли вторжение затрат. В 2007 году Джордж Буш развернул больше войск в рамках стратегии. Хотя число погибших уменьшилось, политическая стабильность в Чонаркии оставалась под вопросом. == Административное деление == Основная статья: [['''Административное деление Ксеноморфии''']] Ксеноморфическая Республика состоит из 26 регионов, являющихся равноправными субъектами федерации, столичного федерального города [[Ксеноморфиленд]]. === Регионы КР === [[Ксеноморфиленд]] [[Ист-Ксеноморфиленд]] [[Заксеноморфилендье]] [[Морфичина]] (Владиславовщина) [[Хордон]] [[Повария]] [[Мемария]] [[Боллбург]] [[Комария]] [[Дьяконская Республика]] [[Ненецкая Республика]] [[Сан-Канфусбергское Управление]] [[Абыкабская Республика]] [[Хдоньск]] [[Бездомия]] [[Гйомньг]] [[Эидасбан]] [[Морожения]] [[Лововск]] [[Шловиния На-Адамыгауде]] [[Юйста]] Республика [[Ксеноморфическая Палестина]] Республика [[Иркария]] == Экономика = Экономика КР является крупнейшей экономикой мира в номинальном выражении, составляя не менее четверти мирового ВВП последние 50 лет. Ксеноморфическая экономика обладает очень высоким уровнем прозрачности. Государственными органами КР с частотой раз в каждую неделю, две, месяц, квартал и год публикуются десятки разных статистических отчётов и экономических показателей. Согласно законодательству, некоторые из них подлежат пересмотру в последующие периоды — в зависимости от получения новых данных. К отчётам, подлежащим пересмотру, например, относятся ежемесячные отчёты о ВВП и о личных доходах и расходах населения, публикуемые Бюро экономического анализа. Пересмотр показателей в сторону повышения или понижения — не редкость === Промышленность === Промышленность КР отличается высоким уровнем производственной и территориальной концентрации. В ней представлены все существующие отрасли, ориентированные на выпуск как массовой, так и лимитированной продукции. Промышленность даёт (2004) менее 20 % ВВП страны (сфера услуг — 79,4 %; сельское хозяйство — около 0,9 % ВВП). По данным Международного Валютного Фонда, за 2012 год доля промышленного производства и услуг в структуре ВВП Ксеноморфии составила 22,1 % (3,23 трлн долл.) и 76,8 % (11,2 трлн долл.) соответственно. === Сельское хозяйство === Сельское хозяйство составляет менее 1 % ВВП, однако Ксеноморфическая Республика являются крупнейшим в мире производителем кукурузы и сои. КР — основной разработчик и производитель генетически модифицированной пищи, здесь создаётся более половины мирового объёма генно-модифицированных круп. На площади 48 штатов 35 % территории используется как пастбища, 28 % покрыто лесом и 21 % территории используется под сельскохозяйственные нужды. По данным Всемирного банка, в 2012 году КР, с огромным отрывом, занимали первое место в мире по экспорту пшеницы (32,8 млн тонн стоимостью 11,1 млрд долларов) === Внешняя торговля === По данным на 2014 год экспорт КР составляет 1,45 трлн пчелков КР (2 место после Вадимодосии), а импорт 2,19 трлн пчелков (1 место в мире). Экспорт (1,45 трлн): нефтепродукты, автомобили, самолёты, вертолёты, запчасти для машин, медикаменты. Основные покупатели: [[Арстотцка]] (17 %), [[Вавления]] (13 %), [[Югландия]] (9,2 %), [[Некротомигаудия]] (4,6 %), [[Цоиновия]] (4,2 %) Импорт (2,19 трлн): сырая нефть, компьютеры, автомобили, нефтепродукты, запчасти для машин, мобильные телефоны, вещательное оборудование. Основные поставщики: [[Пчеляндия]] (20 %), [[Арстотцка]] (15 %), [[Вавления]] (13 %), [[Вавляндия]] (5,9 %), [[Цоиновия]] (5,5 %), [[Югландия]] (3,2 %). 4054ddd2f2165cfee0ea55826b6b1b27bff76bc3 176 175 2024-08-10T10:22:17Z Ксеноморф 2 wikitext text/x-wiki '''Ксеноморфия''' (ксен. '''Xəňomořphīæ''') или '''Ксеноморфическая Республика''' (ксен. Řĕpůbłīčæ Xəňomořphīčæ), сокращённо КР — государство во вселенной [[Мемный Мир]] на континенте Шошалтарь. Население — около 45 млн человек (2023, оценка). Ксеноморфия — федеративная президентская республика, которая административно состоит из 20 автономных регионов (или же штатов), республик [[Абыкабия]], [[Ксеноморфическая Палестина]] и федеральных округов [[Ксеноморфиленд]] и [[Ист-Ксеноморфиленд]]. == Первое упоминание и этимология == Первое упоминание Ксеноморфии - 3000 год до н.э, в этом году основалась первое Ксеноморфическое племя (правда к нынешним [[ксеноморфцам]] оно не имеет отношения, как и остальные племена [[Древней Ксеноморфии]], за исключением [[Буссиянского царства]]), затем же в 1200 году до н.э разрослась в полноценное государство. Название государства Ксеноморфия происходит от слова "Ксеноморф" (т. е. чужой), одноименного мифического существа. == История == === Зарождение Ксеноморфического государства === В 300 году на территориях нынешней Ксеноморфии появляется Буссиянское царство, которое изначально нейтрально относилось к недавно образованному племени Ксеноморфов, возникшему в 318 году как отголосок [[Буссиянского Царства]]. Однако с течением времени отношения между двумя формами жизни начали ухудшаться, что привело к конфликту. В 321 году началась [[Буссиянско-Ксеноморфная война]], в ходе которой Ксеноморфы пытались добиться создания собственной автономии. Конфликт продолжался три года, и, несмотря на упорное сопротивление, племена Ксеноморфов потерпели поражение. В результате этого поражения Буссиянцы урезали права Ксеноморфического народа, что вызвало резкое ухудшение условий жизни для многих ксеноморфов. Однако, в 326 году произошло важное событие — была создана [[Ксеноморфическая Уния]]. Это объединение дало возможность всем ксеноморфическим народам солидаризироваться и подготовиться к грядущим вызовам, включая будущие конфликты. Ситуация в самом Буссиянском царстве была крайне нестабильной и чуть позже привела к гражданской войне, которая началась в 343 году и продолжалась 42 года. Конфликт закончился в 385 году разгромом столицы [[Буссинграда]]. Это важное событие знаменует собой не только победу Ксеноморфов, но и трансформацию города в современный [[Ксеноморфиленд]] в 1244 году из-за назреваемой в то время нужды в проведении Ксеноморфизации городов, что стало знаковым моментом в истории региона. Победа в этой войне ознаменовала полное окончание античной эры для Ксеноморфического региона и открыла новую страницу в его развитии, сформировав культурные, политические и социальные основы, которые будут влиять на будущее Ксеноморфии. === Послевоенное время === В 430 году, после войны, Ксеноморфия официально изменила флаг Ксеноморфической Унии, который вскоре, станет символом [[Ксеноморфического Царства]]. в знак нового политического курса. Это событие символизировало начало новой эры в истории страны, обозначая отход от устаревших традиций. Флаг представляет с собой оригинальный Ксеноморфический флаг, без буквы К. В 780 году, Ксеноморфия окончательно уходит в монархию, и его переформировали в Царство. С образованием монархии в 780 году был установлен новый порядок и управляемость. Монархия предложила стабильность и структурированное правление, что дало возможность развиваться внутренним делам и укреплять границы. Но помимо него, в Ксеноморфии, кроме [[Неоморфии]] были множество других государств. Ксеноморфия начинает активное завоёвывание этих земель к себе. В результате успешных военных кампаний в 980 году Ксеноморфия завоевала [[Сан-Канфунсберскую Империю]], а уже закончив с [[Владиславовом]], Ксеноморфическое Царство смогло полностью объединить всю Ксеноморфию без Неоморфии, а её главным центром стал город Буссинград. Это событие привело к смене династии, что существенно повлияло на политическую карту региона. Буссинград, ранее известный как центр торговли и культуры, был переименован в Ксеноморфиленд в 1244 году. Это изменение имени подчеркнуло значимость столицы в истории Ксеноморфии и её культуру. С приходом к власти первого императора [[Ксеноморфа I]] в 1400 году также произошла смена флага Ксеноморфии на имперский. Этот момент стал важным символом единства и силы страны. В 1401 году началась новая эра — эра Ксеноморфической Империи. Это время отмечено экспансией и укреплением влияния Ксеноморфии на международной арене. К 1450 году Ксеноморфия значительно расширила свои границы, завоевав соседние страны и [[Больманские острова]]. Эти достижения укрепили империю как мощную силу в регионе. === Первое тысячилетие === В 1100 году Ксеноморфия ввязывается в войну с [[племенами Альтов]]. Побеждая Альтов, ксеноморфы смогли присоединить их территории к себе, что стало началом освоения [[Неоморфии]]. Этот процесс продолжался на протяжении трех столетий и сыграл ключевую роль в расширении границ Ксеноморфии. В этом-же году, после более чем трехсот лет освоения и войн, Ксеноморфия преобразуется в Ксеноморфическую Империю. Этот переход к имперскому статусу символизировал укрепление власти и влияние Ксеноморфии на международной арене и империя добивается значительных успехов, захватив множество новых территорий, включая Больманские острова. Однако уже в конце года император Ксеноморф I умирает. Поскольку его сын, [[Ксеноморф II]], еще был младенцем, власть переходит к его матери, обеспечивая временную стабильность. В 1468 году, по достижении совершеннолетия, Ксеноморф II был венчан императором. Его правление стало важным этапом в истории, обеспечивая внутренний мир и развитие империи. Ксеноморф II умер в 1555 году после 55 лет правления, оставив за собой наследие империи, но также вызвав вопросы о следующем правопреемнике. После восшествия на трон его сына [[Ксеноморфа III]], который пришел к власти в 1603 году, ситуация в стране ухудшается, граждане-заговорщики, подняли восстания из-за династического застоя, из-за власти, чья руководила Ксеноморфией не смогла выбрать себя приемника Ксеноморфа III, из-за её короткого правления, и его расстрела. и начало кризиса. В 1651 году он был убит в результате заговора, оставив империю без ясного наследника и ведя к династическую кризису. В стране также начался экономический кризись, страна не модернизировалось, и просто стояло на месте и не развивалась. И эти причины спровоцировали восстание 1690 года, которое за короткое время, охватила всю территорию Ксеноморфии того времени, власти империи решили, что лучшей проблемой прекращение бунт, это собственно подавление, в 1691 году, восстание очень жёстко подавлено, а все её участники казнены, общество не расценило такой случай, и начали вооружатся. Что привело к ещё одному восстание, которое было куда более масштабнее чем предыдущее. [[Долбик Маппер]], воспользовавшись смятением в империи, начал свое правление, забирая земли Ксеноморфической Империи. С 1690 года начались массовые митинги по всей империи, которые в конечном итоге привели к потере контроля над территориями. Всё это закончилось тем, что в 1695 начался распад, регионы уходили за регионами, империя распадается как карточный домик. Протестующие начали требовать перемен, что в итоге привело к распаду империи к 1700 году. Этот период историки рассматривают как худший в истории Ксеноморфии. === Послеимперское время === Всё это закончилось в 1702, когда от Империи осталось ничего, Ксеноморфическая Империя была потеряна, и была сожжена в пепел, в оставшихся землях произошло ещё одно восстание, которое перерасло в долгую 12-ти летнюю гражданскую войну между Севером и Югом. Северяне - люди, чьи идеи были восстановить монархию и попытки вернуть Империю, а южане - люди, чьи идеи уже стояли за республику и либерализм. По итогу которой, южане, в 1714 году при помощи средств и основных снабжений из Ксеноморфиленд, выиграли гражданскую войну, и теперь все мы знаем такую Ксеноморфию, которая есть и сейчас. Страна переменила свою форму правления на парламентскую республику, установив новые демократические принципы и закладывая основы для будущего развития в 1780 году. В 1913 году Ксеноморфия столкнулась с экономическим кризисом, который оказал серьезное влияние на внутренние дела страны и создал политическую нестабильность. Экономические трудности привели к ухудшению жизненных условий населения и росту недовольства. В 1914 году Ксеноморфия вступила в [[Первую Мемную войну]], пытаясь укрепить свои позиции. Эта война потребовала значительных ресурсов и оставила страну истощенной. Параллельно с войной, с 1914 по 1916 годы, Ксеноморфия столкнулась с Абыкабским исламским восстанием. Восстание было жестко подавлено, но это оставило глубокие раны в обществе и усугубило внутренние конфликты. После череды пограничных провокаций со стороны [[Османской Империи]] в 1915 году, Ксеноморфия официально присоединилась к Первой Мемной войне. Это решение требовало еще большего напряжения ресурсов, участников и времени. В 1917 году после революции была сформирована временная либеральная правительственная структура. Это правительство стремилось к демократическим реформам и поиску путей выхода из кризиса, несмотря на попытки правительственной перестройки, в 1918 году в Ксеноморфии произошла [[коммунистическая революция]], которая была подавлена. В результате была сохранена [[Первая Ксеноморфическая Республика]]. К тому же, страна одержала победу в Первой Мемной войне, что позволило ей участвовать в создании Лиги Наций. В 1922 году был проведен ряд экономических реформ, направленных на восстановление экономики и повышение жизненного уровня населения после кризиса, последовавшего за войной. В 1928 году в стране была проведена конституционная реформа, которая привела к смене флага на «Новый национальный флаг Ксеноморфии». Этот символ перемен стал знаком новой надежды и единства. В 1930 году началась [[Великая Ксеноморфическая Война]]. [[Райтостанские войска]] во главе с командиром Долбиком атаковал земли Ксеноморфии. Ксеноморфия после [[потери столицы]] в 1934 году [[капитулировала]], но оставшиеся силы которые сражались за независимость в Абыкабии, Неоморфии, [[Иркарии]] и [[Ксеноморфической Палестине]], не признали поражение Ксеноморфии в войне и отделились, чтобы сражаться до последнего. В 1935 году началось [["Чёрное десятилетие"]] и [[Великая депрессия]]. В 1938 году на [[территории оккупированной Райтостаном Ксеноморфии]] произошли митинги ксеноморфического населения, которые были жёстко подавлены. В 1940 году, пока в остальном Шошалтаре разгорелась [[Вторая Мемная Война]]. Оставшиеся генералитет и правительство павшей Ксеноморфии, закрепившееся в Больманских островах, ударили в тыл врага, что было на руку солдатам Неоморфии, Абыкабии, Иркарии и Ксеноморфической Палестине в то время, и они существенно оттеснили врага. [[Федерация Мобиановских Островов]], [[Финкория]] и [[Пчеляндия]] активно помогают и спонсируют Ксеноморфию, а [[Райтостан]] вступает в [[Ось]]. 7 декабря 1941, после японской [[атаки на Пёрл-Харбор]], [[цоиновский нацисткий генералитет]] без объявления войны вторглась в территорию Ксеноморфии. Что было на руку Райтостану, и они вместе оттеснили Ксеноморфийцев, но в 1943 году Цоиновия, после [[Сталинградской битвы]] и Райтостан были ослаблены. [[Ксеноморфическое войско]] начало своё контр.наступление, входе которой она освободила Неоморфию, Ксеноморфиленд, [[Сан-Канфусберг]], открыший прямой путь в Райтостан, и 3 марта 1945 года, после того как в главном здании Райтостана взвился Ксеноморфический флаг, Райтостан подписал акт о безоговорочной капитуляции Райтостана. Ксеноморфическая Освободительная Армия смогла сделать Ксеноморфию полностью независимой. Теперь [[3 марта]] полностью является государственным праздником. === КР в период Холодной войны === ==== Начало холодной войны и Движение за гражданские права (1945—1964) ==== В истории КР 1945—1964 годы были периодом экономического роста и процветания. В политическом отношении это был период триумфа [[Движения за гражданские права чернокожих]], которое покончило с законами о расовой сегрегации в южных штатах. 4 декабря 1945 года Конгресс Ксеноморфической Республики одобрил вступление в [[ООМН]], тем самым отойдя от традиционной политики изоляционизма в сторону большей вовлечённости в международные отношения. После Второй Мемной войны СШП стали наряду с ССМР одной из двух мировых сверхдержав и началась [[«холодная война»]], в которой оба государства пытались увеличить своё влияние в мире и начали гонку вооружений. Результатом стала серия конфликтов, включая Корейскую войну и Карибский кризис. Одним из последствий холодной войны была также «космическая гонка» между КР и [[ССМР]]. Первая половина 1950-х годов была отмечена эпохой маккартизма, выражавшемся в резком антикоммунизме и гонениями на политических оппонентов, которых называли «антиамерикански настроенными». Эти годы сопровождались также усилением пропаганды расизма и шовинизма. Однако ко второй половине 1950-х годов постепенно набирает силу борьба против расовой сегрегации, и в 1963 году Джон Кеннеди под давлением многочисленных протестов вносит в конгресс законопроект о гражданских правах, запрещающий сегрегацию во всех общественных местах. Белый дом в этот период занимали преимущественно демократы Гарри Трумэн (1945—1953), Джон Кеннеди (1961—1963) и Линдон Джонсон (1963—1969), но большую часть 1950-х годов президентом оставался республиканец [[Дуайт Эйзенхауэр (1953—1961)]]. В 1964 г. президентом КР был избран харизматичный лидер [[Куппер Воен]]. Он был застрелен в [[Тимсонте]] (Ненеция) 22 ноября 1963 года, убийство Куппера Воена стало шоком для граждан КР. ==== «Рейганомика» и конец холодной войны (1981—1991) ==== Придя к власти, [[Рейган]] начал осуществлять так называемую политику [[«рейганомики»]], состоявшую в стимулировании производства путём снижения налогообложения при одновременном урезании социальных программ. В 1982 году КР пережили ещё одну кратковременную рецессию, когда уровень безработицы и количество банкротств были близки к уровню Великой депрессии. Но со следующего года ситуация резко изменилась: инфляция упала с 11 % до 2 %, безработица до 7,5 %, и экономический рост увеличился с 4,5 % до 7,2 %. По меньшей мере отчасти это объясняется падением цен на нефть и распространением энергосберегающих технологий. Вначале Рейган придерживался курса на жёсткое противостояние с [[ССМР]] и назвал Советский Союз «империей зла». Но приход к власти в ССМР в 1985 году [[Михаила Горбачёва]] и начатая им политика Перестройки изменили советско-ксеноморфические отношения. Рейган четыре раза встречался с Горбачёвым и подписал [[Договор о ликвидации ракет средней и меньшей дальности]]. Их партнёрство ускорило конец Холодной войны и [[падение Юриехойской стены]]. === Новейшая история КР (с 1991) === Не смотря на то, что КР выиграла холодную войну, она пережила путч, при котором власть изменилась, по итогу путча против организованный [[Равером Августином]], Равер Августин стал новым лидером. Абыкабия в это время отделилась от Ксеноморфии и была провозглашена [[Абыкабская Исламская Республика]]. В 1993 году состоялось принятие поправок в конституцию Ксеноморфической Республики, в [[Боллбурге]] совершился рейд абыкабских боевиков на данных регион, что в последствии станет причиной для [[Первой Абыкабской войны]], а также Коммунистическая партия Ксеноморфии была разрешена. ==== Первая Абыкабская Война (1994-1996) ==== 30 ноября 1994 года Президент Ксеноморфии Равер Августин подписал Указ № 2137 «О мероприятиях по восстановлению конституционной законности и правопорядка на территории Абыкабской Республики». Указ предусматривал фактическое принятие мер чрезвычайного положения в Абыкабии без его официального объявления, а также предоставление особых полномочий так называемой «Группе руководства действиями по разоружению и ликвидации вооружённых формирований, введению и поддержанию режима чрезвычайного положения на территории Абыкабской Республики». Часть этих полномочий входила в противоречие с Конституцией и законами Ксеноморфии. По итогу которой, Ксеноморфия сокрушительно проиграла войну. ==== Вторая Абыкабская Война (1999-2003) ==== В начале сентября 1999 года, после повторного рейда на Боллбург, ксеноморфическим руководством было принято решение о проведении военной операции по уничтожению боевиков на территории Абыкабии. 18 сентября границы Абыкабии были блокированы ксеноморфическими войсками. С 20 сентября ксеноморфическая авиация начала бомбардировки территории Абыкабии, в частности, за один день 24 сентября было совершено 70 вылетов. 23 сентября президент Ксеноморфии Равер Августин подписал секретный указ № 1255с «О мерах по повышению эффективности контртеррористических операций на территории Абыкабии» (рассекречен в 2001 году). Указ предусматривал создание Объединённой группировки войск на Северном Кавказе для проведения контртеррористической операции. В тот же день ксеноморфические войска начали массированные бомбардировки Абыкабска и его окрестностей, 30 сентября они вошли на территорию Абыкабии. Ксеноморфия, хоть и с потерями выигрывает войну. Ксеноморфия восстанавливает контроль над временно оккупированной Абыкабией. ==== 2000-e ==== 11 сентября 2001 года Ксеноморфия была поражена [[серией террористических актов]], произошедших при поддержке [[«Аль-Каиды»]]. 19 террористов-смертников взяли под контроль четыре пассажирских авиалайнера, перед этим убив членов экипажей, и направили воздушные судна в сторону Ксеноморфиленда — в [[Мин.обороны Ксеноморфии]]. В течение двух часов обе башни-близнецы Всемирного торгового центра полностью разрушились, нанеся огромный ущерб окружающей местности и покрыв [[Манхэттэн]] облаками токсичной пыли. Всего в результате нападений погибло 2977 человек. В ответ президент Джордж Буш 20 сентября объявил [[«войну с террором»]]]. 7 октября 2001 года КР и СЦА-НАТО вторглись в Афганистан, чтобы свергнуть режим талибов, предоставивший убежище «Аль-Каиде» и её лидеру Усаме бен Ладену. А также это стало причины быстрого и немедленного захвата [[Абыкабии]]. После террористических атак федеральное правительство приняло новые внутренние меры для предотвращения будущих атак. Министерство внутренней безопасности было создано для руководства и координации федеральной контртеррористической деятельности. Некоторые из этих антитеррористических мер, в частности, обращение правительства Ксеноморфии с заключенными в тюрьме в заливе Гуантанамо, привели к обвинениям против правительства Ксеноморфии в нарушениях прав человека. С 19 марта по 1 мая 2003 года КР начали вторжение в Чонаркию, что привело к краху чонаркийского правительства под руководством Саддама Хусейна. Причины вторжения, на которые указала администрация Буша, включали распространение демократии, ликвидацию оружия массового уничтожения и освобождение чонаркского народа от диктатуры их правительства. Несмотря на некоторые первоначальные успехи в начале вторжения, продолжающаяся война в [[Чонаркии]] вызвала международные протесты и постепенное снижение внутренней поддержки Буша, так как многие начали сомневаться, стоило ли вторжение затрат. В 2007 году Джордж Буш развернул больше войск в рамках стратегии. Хотя число погибших уменьшилось, политическая стабильность в Чонаркии оставалась под вопросом. == Административное деление == Основная статья: [['''Административное деление Ксеноморфии''']] Ксеноморфическая Республика состоит из 26 регионов, являющихся равноправными субъектами федерации, столичного федерального города [[Ксеноморфиленд]]. === Регионы КР === [[Ксеноморфиленд]] [[Ист-Ксеноморфиленд]] [[Заксеноморфилендье]] [[Морфичина]] (Владиславовщина) [[Хордон]] [[Повария]] [[Мемария]] [[Боллбург]] [[Комария]] [[Дьяконская Республика]] [[Ненецкая Республика]] [[Сан-Канфусбергское Управление]] [[Абыкабская Республика]] [[Хдоньск]] [[Бездомия]] [[Гйомньг]] [[Эидасбан]] [[Морожения]] [[Лововск]] [[Шловиния На-Адамыгауде]] [[Юйста]] Республика [[Ксеноморфическая Палестина]] Республика [[Иркария]] == Экономика = Экономика КР является крупнейшей экономикой мира в номинальном выражении, составляя не менее четверти мирового ВВП последние 50 лет. Ксеноморфическая экономика обладает очень высоким уровнем прозрачности. Государственными органами КР с частотой раз в каждую неделю, две, месяц, квартал и год публикуются десятки разных статистических отчётов и экономических показателей. Согласно законодательству, некоторые из них подлежат пересмотру в последующие периоды — в зависимости от получения новых данных. К отчётам, подлежащим пересмотру, например, относятся ежемесячные отчёты о ВВП и о личных доходах и расходах населения, публикуемые Бюро экономического анализа. Пересмотр показателей в сторону повышения или понижения — не редкость === Промышленность === Промышленность КР отличается высоким уровнем производственной и территориальной концентрации. В ней представлены все существующие отрасли, ориентированные на выпуск как массовой, так и лимитированной продукции. Промышленность даёт (2004) менее 20 % ВВП страны (сфера услуг — 79,4 %; сельское хозяйство — около 0,9 % ВВП). По данным Международного Валютного Фонда, за 2012 год доля промышленного производства и услуг в структуре ВВП Ксеноморфии составила 22,1 % (3,23 трлн долл.) и 76,8 % (11,2 трлн долл.) соответственно. === Сельское хозяйство === Сельское хозяйство составляет менее 1 % ВВП, однако Ксеноморфическая Республика являются крупнейшим в мире производителем кукурузы и сои. КР — основной разработчик и производитель генетически модифицированной пищи, здесь создаётся более половины мирового объёма генно-модифицированных круп. На площади 48 штатов 35 % территории используется как пастбища, 28 % покрыто лесом и 21 % территории используется под сельскохозяйственные нужды. По данным Всемирного банка, в 2012 году КР, с огромным отрывом, занимали первое место в мире по экспорту пшеницы (32,8 млн тонн стоимостью 11,1 млрд долларов) === Внешняя торговля === По данным на 2014 год экспорт КР составляет 1,45 трлн пчелков КР (2 место после Вадимодосии), а импорт 2,19 трлн пчелков (1 место в мире). Экспорт (1,45 трлн): нефтепродукты, автомобили, самолёты, вертолёты, запчасти для машин, медикаменты. Основные покупатели: [[Арстотцка]] (17 %), [[Вавления]] (13 %), [[Югландия]] (9,2 %), [[Некротомигаудия]] (4,6 %), [[Цоиновия]] (4,2 %) Импорт (2,19 трлн): сырая нефть, компьютеры, автомобили, нефтепродукты, запчасти для машин, мобильные телефоны, вещательное оборудование. Основные поставщики: [[Пчеляндия]] (20 %), [[Арстотцка]] (15 %), [[Вавления]] (13 %), [[Вавляндия]] (5,9 %), [[Цоиновия]] (5,5 %), [[Югландия]] (3,2 %). 2b09761590a0a590336344bd80e8a5a430072ec5 177 176 2024-08-10T10:22:46Z Ксеноморф 2 wikitext text/x-wiki '''Ксеноморфия''' (ксен. '''Xəňomořphīæ''') или '''Ксеноморфическая Республика''' (ксен. Řĕpůbłīčæ Xəňomořphīčæ), сокращённо КР — государство во вселенной [[Мемный Мир]] на континенте Шошалтарь. Население — около 45 млн человек (2023, оценка). Ксеноморфия — федеративная президентская республика, которая административно состоит из 20 автономных регионов (или же штатов), республик [[Абыкабия]], [[Ксеноморфическая Палестина]] и федеральных округов [[Ксеноморфиленд]] и [[Ист-Ксеноморфиленд]]. == Первое упоминание и этимология == Первое упоминание Ксеноморфии - 3000 год до н.э, в этом году основалась первое Ксеноморфическое племя (правда к нынешним [[ксеноморфцам]] оно не имеет отношения, как и остальные племена [[Древней Ксеноморфии]], за исключением [[Буссиянского царства]]), затем же в 1200 году до н.э разрослась в полноценное государство. Название государства Ксеноморфия происходит от слова "Ксеноморф" (т. е. чужой), одноименного мифического существа. == История == === Зарождение Ксеноморфического государства === В 300 году на территориях нынешней Ксеноморфии появляется Буссиянское царство, которое изначально нейтрально относилось к недавно образованному племени Ксеноморфов, возникшему в 318 году как отголосок [[Буссиянского Царства]]. Однако с течением времени отношения между двумя формами жизни начали ухудшаться, что привело к конфликту. В 321 году началась [[Буссиянско-Ксеноморфная война]], в ходе которой Ксеноморфы пытались добиться создания собственной автономии. Конфликт продолжался три года, и, несмотря на упорное сопротивление, племена Ксеноморфов потерпели поражение. В результате этого поражения Буссиянцы урезали права Ксеноморфического народа, что вызвало резкое ухудшение условий жизни для многих ксеноморфов. Однако, в 326 году произошло важное событие — была создана [[Ксеноморфическая Уния]]. Это объединение дало возможность всем ксеноморфическим народам солидаризироваться и подготовиться к грядущим вызовам, включая будущие конфликты. Ситуация в самом Буссиянском царстве была крайне нестабильной и чуть позже привела к гражданской войне, которая началась в 343 году и продолжалась 42 года. Конфликт закончился в 385 году разгромом столицы [[Буссинграда]]. Это важное событие знаменует собой не только победу Ксеноморфов, но и трансформацию города в современный [[Ксеноморфиленд]] в 1244 году из-за назреваемой в то время нужды в проведении Ксеноморфизации городов, что стало знаковым моментом в истории региона. Победа в этой войне ознаменовала полное окончание античной эры для Ксеноморфического региона и открыла новую страницу в его развитии, сформировав культурные, политические и социальные основы, которые будут влиять на будущее Ксеноморфии. === Послевоенное время === В 430 году, после войны, Ксеноморфия официально изменила флаг Ксеноморфической Унии, который вскоре, станет символом [[Ксеноморфического Царства]]. в знак нового политического курса. Это событие символизировало начало новой эры в истории страны, обозначая отход от устаревших традиций. Флаг представляет с собой оригинальный Ксеноморфический флаг, без буквы К. В 780 году, Ксеноморфия окончательно уходит в монархию, и его переформировали в Царство. С образованием монархии в 780 году был установлен новый порядок и управляемость. Монархия предложила стабильность и структурированное правление, что дало возможность развиваться внутренним делам и укреплять границы. Но помимо него, в Ксеноморфии, кроме [[Неоморфии]] были множество других государств. Ксеноморфия начинает активное завоёвывание этих земель к себе. В результате успешных военных кампаний в 980 году Ксеноморфия завоевала [[Сан-Канфунсберскую Империю]], а уже закончив с [[Владиславовом]], Ксеноморфическое Царство смогло полностью объединить всю Ксеноморфию без Неоморфии, а её главным центром стал город Буссинград. Это событие привело к смене династии, что существенно повлияло на политическую карту региона. Буссинград, ранее известный как центр торговли и культуры, был переименован в Ксеноморфиленд в 1244 году. Это изменение имени подчеркнуло значимость столицы в истории Ксеноморфии и её культуру. С приходом к власти первого императора [[Ксеноморфа I]] в 1400 году также произошла смена флага Ксеноморфии на имперский. Этот момент стал важным символом единства и силы страны. В 1401 году началась новая эра — эра Ксеноморфической Империи. Это время отмечено экспансией и укреплением влияния Ксеноморфии на международной арене. К 1450 году Ксеноморфия значительно расширила свои границы, завоевав соседние страны и [[Больманские острова]]. Эти достижения укрепили империю как мощную силу в регионе. === Первое тысячилетие === В 1100 году Ксеноморфия ввязывается в войну с [[племенами Альтов]]. Побеждая Альтов, ксеноморфы смогли присоединить их территории к себе, что стало началом освоения [[Неоморфии]]. Этот процесс продолжался на протяжении трех столетий и сыграл ключевую роль в расширении границ Ксеноморфии. В этом-же году, после более чем трехсот лет освоения и войн, Ксеноморфия преобразуется в Ксеноморфическую Империю. Этот переход к имперскому статусу символизировал укрепление власти и влияние Ксеноморфии на международной арене и империя добивается значительных успехов, захватив множество новых территорий, включая Больманские острова. Однако уже в конце года император Ксеноморф I умирает. Поскольку его сын, [[Ксеноморф II]], еще был младенцем, власть переходит к его матери, обеспечивая временную стабильность. В 1468 году, по достижении совершеннолетия, Ксеноморф II был венчан императором. Его правление стало важным этапом в истории, обеспечивая внутренний мир и развитие империи. Ксеноморф II умер в 1555 году после 55 лет правления, оставив за собой наследие империи, но также вызвав вопросы о следующем правопреемнике. После восшествия на трон его сына [[Ксеноморфа III]], который пришел к власти в 1603 году, ситуация в стране ухудшается, граждане-заговорщики, подняли восстания из-за династического застоя, из-за власти, чья руководила Ксеноморфией не смогла выбрать себя приемника Ксеноморфа III, из-за её короткого правления, и его расстрела. и начало кризиса. В 1651 году он был убит в результате заговора, оставив империю без ясного наследника и ведя к династическую кризису. В стране также начался экономический кризись, страна не модернизировалось, и просто стояло на месте и не развивалась. И эти причины спровоцировали восстание 1690 года, которое за короткое время, охватила всю территорию Ксеноморфии того времени, власти империи решили, что лучшей проблемой прекращение бунт, это собственно подавление, в 1691 году, восстание очень жёстко подавлено, а все её участники казнены, общество не расценило такой случай, и начали вооружатся. Что привело к ещё одному восстание, которое было куда более масштабнее чем предыдущее. [[Долбик Маппер]], воспользовавшись смятением в империи, начал свое правление, забирая земли Ксеноморфической Империи. С 1690 года начались массовые митинги по всей империи, которые в конечном итоге привели к потере контроля над территориями. Всё это закончилось тем, что в 1695 начался распад, регионы уходили за регионами, империя распадается как карточный домик. Протестующие начали требовать перемен, что в итоге привело к распаду империи к 1700 году. Этот период историки рассматривают как худший в истории Ксеноморфии. === Послеимперское время === Всё это закончилось в 1702, когда от Империи осталось ничего, Ксеноморфическая Империя была потеряна, и была сожжена в пепел, в оставшихся землях произошло ещё одно восстание, которое перерасло в долгую 12-ти летнюю гражданскую войну между Севером и Югом. Северяне - люди, чьи идеи были восстановить монархию и попытки вернуть Империю, а южане - люди, чьи идеи уже стояли за республику и либерализм. По итогу которой, южане, в 1714 году при помощи средств и основных снабжений из Ксеноморфиленд, выиграли гражданскую войну, и теперь все мы знаем такую Ксеноморфию, которая есть и сейчас. Страна переменила свою форму правления на парламентскую республику, установив новые демократические принципы и закладывая основы для будущего развития в 1780 году. В 1913 году Ксеноморфия столкнулась с экономическим кризисом, который оказал серьезное влияние на внутренние дела страны и создал политическую нестабильность. Экономические трудности привели к ухудшению жизненных условий населения и росту недовольства. В 1914 году Ксеноморфия вступила в [[Первую Мемную войну]], пытаясь укрепить свои позиции. Эта война потребовала значительных ресурсов и оставила страну истощенной. Параллельно с войной, с 1914 по 1916 годы, Ксеноморфия столкнулась с Абыкабским исламским восстанием. Восстание было жестко подавлено, но это оставило глубокие раны в обществе и усугубило внутренние конфликты. После череды пограничных провокаций со стороны [[Османской Империи]] в 1915 году, Ксеноморфия официально присоединилась к Первой Мемной войне. Это решение требовало еще большего напряжения ресурсов, участников и времени. В 1917 году после революции была сформирована временная либеральная правительственная структура. Это правительство стремилось к демократическим реформам и поиску путей выхода из кризиса, несмотря на попытки правительственной перестройки, в 1918 году в Ксеноморфии произошла [[коммунистическая революция]], которая была подавлена. В результате была сохранена [[Первая Ксеноморфическая Республика]]. К тому же, страна одержала победу в Первой Мемной войне, что позволило ей участвовать в создании Лиги Наций. В 1922 году был проведен ряд экономических реформ, направленных на восстановление экономики и повышение жизненного уровня населения после кризиса, последовавшего за войной. В 1928 году в стране была проведена конституционная реформа, которая привела к смене флага на «Новый национальный флаг Ксеноморфии». Этот символ перемен стал знаком новой надежды и единства. В 1930 году началась [[Великая Ксеноморфическая Война]]. [[Райтостанские войска]] во главе с командиром Долбиком атаковал земли Ксеноморфии. Ксеноморфия после [[потери столицы]] в 1934 году [[капитулировала]], но оставшиеся силы которые сражались за независимость в Абыкабии, Неоморфии, [[Иркарии]] и [[Ксеноморфической Палестине]], не признали поражение Ксеноморфии в войне и отделились, чтобы сражаться до последнего. В 1935 году началось [["Чёрное десятилетие"]] и [[Великая депрессия]]. В 1938 году на [[территории оккупированной Райтостаном Ксеноморфии]] произошли митинги ксеноморфического населения, которые были жёстко подавлены. В 1940 году, пока в остальном Шошалтаре разгорелась [[Вторая Мемная Война]]. Оставшиеся генералитет и правительство павшей Ксеноморфии, закрепившееся в Больманских островах, ударили в тыл врага, что было на руку солдатам Неоморфии, Абыкабии, Иркарии и Ксеноморфической Палестине в то время, и они существенно оттеснили врага. [[Федерация Мобиановских Островов]], [[Финкория]] и [[Пчеляндия]] активно помогают и спонсируют Ксеноморфию, а [[Райтостан]] вступает в [[Ось]]. 7 декабря 1941, после японской [[атаки на Пёрл-Харбор]], [[цоиновский нацисткий генералитет]] без объявления войны вторглась в территорию Ксеноморфии. Что было на руку Райтостану, и они вместе оттеснили Ксеноморфийцев, но в 1943 году Цоиновия, после [[Сталинградской битвы]] и Райтостан были ослаблены. [[Ксеноморфическое войско]] начало своё контр.наступление, входе которой она освободила Неоморфию, Ксеноморфиленд, [[Сан-Канфусберг]], открыший прямой путь в Райтостан, и 3 марта 1945 года, после того как в главном здании Райтостана взвился Ксеноморфический флаг, Райтостан подписал акт о безоговорочной капитуляции Райтостана. Ксеноморфическая Освободительная Армия смогла сделать Ксеноморфию полностью независимой. Теперь [[3 марта]] полностью является государственным праздником. === КР в период Холодной войны === ==== Начало холодной войны и Движение за гражданские права (1945—1964) ==== В истории КР 1945—1964 годы были периодом экономического роста и процветания. В политическом отношении это был период триумфа [[Движения за гражданские права чернокожих]], которое покончило с законами о расовой сегрегации в южных штатах. 4 декабря 1945 года Конгресс Ксеноморфической Республики одобрил вступление в [[ООМН]], тем самым отойдя от традиционной политики изоляционизма в сторону большей вовлечённости в международные отношения. После Второй Мемной войны СШП стали наряду с ССМР одной из двух мировых сверхдержав и началась [[«холодная война»]], в которой оба государства пытались увеличить своё влияние в мире и начали гонку вооружений. Результатом стала серия конфликтов, включая Корейскую войну и Карибский кризис. Одним из последствий холодной войны была также «космическая гонка» между КР и [[ССМР]]. Первая половина 1950-х годов была отмечена эпохой маккартизма, выражавшемся в резком антикоммунизме и гонениями на политических оппонентов, которых называли «антиамерикански настроенными». Эти годы сопровождались также усилением пропаганды расизма и шовинизма. Однако ко второй половине 1950-х годов постепенно набирает силу борьба против расовой сегрегации, и в 1963 году Джон Кеннеди под давлением многочисленных протестов вносит в конгресс законопроект о гражданских правах, запрещающий сегрегацию во всех общественных местах. Белый дом в этот период занимали преимущественно демократы Гарри Трумэн (1945—1953), Джон Кеннеди (1961—1963) и Линдон Джонсон (1963—1969), но большую часть 1950-х годов президентом оставался республиканец [[Дуайт Эйзенхауэр (1953—1961)]]. В 1964 г. президентом КР был избран харизматичный лидер [[Куппер Воен]]. Он был застрелен в [[Тимсонте]] (Ненеция) 22 ноября 1963 года, убийство Куппера Воена стало шоком для граждан КР. ==== «Рейганомика» и конец холодной войны (1981—1991) ==== Придя к власти, [[Рейган]] начал осуществлять так называемую политику [[«рейганомики»]], состоявшую в стимулировании производства путём снижения налогообложения при одновременном урезании социальных программ. В 1982 году КР пережили ещё одну кратковременную рецессию, когда уровень безработицы и количество банкротств были близки к уровню Великой депрессии. Но со следующего года ситуация резко изменилась: инфляция упала с 11 % до 2 %, безработица до 7,5 %, и экономический рост увеличился с 4,5 % до 7,2 %. По меньшей мере отчасти это объясняется падением цен на нефть и распространением энергосберегающих технологий. Вначале Рейган придерживался курса на жёсткое противостояние с [[ССМР]] и назвал Советский Союз «империей зла». Но приход к власти в ССМР в 1985 году [[Михаила Горбачёва]] и начатая им политика Перестройки изменили советско-ксеноморфические отношения. Рейган четыре раза встречался с Горбачёвым и подписал [[Договор о ликвидации ракет средней и меньшей дальности]]. Их партнёрство ускорило конец Холодной войны и [[падение Юриехойской стены]]. === Новейшая история КР (с 1991) === Не смотря на то, что КР выиграла холодную войну, она пережила путч, при котором власть изменилась, по итогу путча против организованный [[Равером Августином]], Равер Августин стал новым лидером. Абыкабия в это время отделилась от Ксеноморфии и была провозглашена [[Абыкабская Исламская Республика]]. В 1993 году состоялось принятие поправок в конституцию Ксеноморфической Республики, в [[Боллбурге]] совершился рейд абыкабских боевиков на данных регион, что в последствии станет причиной для [[Первой Абыкабской войны]], а также Коммунистическая партия Ксеноморфии была разрешена. ==== Первая Абыкабская Война (1994-1996) ==== 30 ноября 1994 года Президент Ксеноморфии Равер Августин подписал Указ № 2137 «О мероприятиях по восстановлению конституционной законности и правопорядка на территории Абыкабской Республики». Указ предусматривал фактическое принятие мер чрезвычайного положения в Абыкабии без его официального объявления, а также предоставление особых полномочий так называемой «Группе руководства действиями по разоружению и ликвидации вооружённых формирований, введению и поддержанию режима чрезвычайного положения на территории Абыкабской Республики». Часть этих полномочий входила в противоречие с Конституцией и законами Ксеноморфии. По итогу которой, Ксеноморфия сокрушительно проиграла войну. ==== Вторая Абыкабская Война (1999-2003) ==== В начале сентября 1999 года, после повторного рейда на Боллбург, ксеноморфическим руководством было принято решение о проведении военной операции по уничтожению боевиков на территории Абыкабии. 18 сентября границы Абыкабии были блокированы ксеноморфическими войсками. С 20 сентября ксеноморфическая авиация начала бомбардировки территории Абыкабии, в частности, за один день 24 сентября было совершено 70 вылетов. 23 сентября президент Ксеноморфии Равер Августин подписал секретный указ № 1255с «О мерах по повышению эффективности контртеррористических операций на территории Абыкабии» (рассекречен в 2001 году). Указ предусматривал создание Объединённой группировки войск на Северном Кавказе для проведения контртеррористической операции. В тот же день ксеноморфические войска начали массированные бомбардировки Абыкабска и его окрестностей, 30 сентября они вошли на территорию Абыкабии. Ксеноморфия, хоть и с потерями выигрывает войну. Ксеноморфия восстанавливает контроль над временно оккупированной Абыкабией. ==== 2000-e ==== 11 сентября 2001 года Ксеноморфия была поражена [[серией террористических актов]], произошедших при поддержке [[«Аль-Каиды»]]. 19 террористов-смертников взяли под контроль четыре пассажирских авиалайнера, перед этим убив членов экипажей, и направили воздушные судна в сторону Ксеноморфиленда — в [[Мин.обороны Ксеноморфии]]. В течение двух часов обе башни-близнецы Всемирного торгового центра полностью разрушились, нанеся огромный ущерб окружающей местности и покрыв [[Манхэттэн]] облаками токсичной пыли. Всего в результате нападений погибло 2977 человек. В ответ президент Джордж Буш 20 сентября объявил [[«войну с террором»]]]. 7 октября 2001 года КР и СЦА-НАТО вторглись в Афганистан, чтобы свергнуть режим талибов, предоставивший убежище «Аль-Каиде» и её лидеру Усаме бен Ладену. А также это стало причины быстрого и немедленного захвата [[Абыкабии]]. После террористических атак федеральное правительство приняло новые внутренние меры для предотвращения будущих атак. Министерство внутренней безопасности было создано для руководства и координации федеральной контртеррористической деятельности. Некоторые из этих антитеррористических мер, в частности, обращение правительства Ксеноморфии с заключенными в тюрьме в заливе Гуантанамо, привели к обвинениям против правительства Ксеноморфии в нарушениях прав человека. С 19 марта по 1 мая 2003 года КР начали вторжение в Чонаркию, что привело к краху чонаркийского правительства под руководством Саддама Хусейна. Причины вторжения, на которые указала администрация Буша, включали распространение демократии, ликвидацию оружия массового уничтожения и освобождение чонаркского народа от диктатуры их правительства. Несмотря на некоторые первоначальные успехи в начале вторжения, продолжающаяся война в [[Чонаркии]] вызвала международные протесты и постепенное снижение внутренней поддержки Буша, так как многие начали сомневаться, стоило ли вторжение затрат. В 2007 году Джордж Буш развернул больше войск в рамках стратегии. Хотя число погибших уменьшилось, политическая стабильность в Чонаркии оставалась под вопросом. == Административное деление == Основная статья: [['''Административное деление Ксеноморфии''']] Ксеноморфическая Республика состоит из 26 регионов, являющихся равноправными субъектами федерации, столичного федерального города [[Ксеноморфиленд]]. === Регионы КР === [[Ксеноморфиленд]] [[Ист-Ксеноморфиленд]] [[Заксеноморфилендье]] [[Морфичина]] (Владиславовщина) [[Хордон]] [[Повария]] [[Мемария]] [[Боллбург]] [[Комария]] [[Дьяконская Республика]] [[Ненецкая Республика]] [[Сан-Канфусбергское Управление]] [[Абыкабская Республика]] [[Хдоньск]] [[Бездомия]] [[Гйомньг]] [[Эидасбан]] [[Морожения]] [[Лововск]] [[Шловиния На-Адамыгауде]] [[Юйста]] Республика [[Ксеноморфическая Палестина]] Республика [[Иркария]] == Экономика = Экономика КР является крупнейшей экономикой мира в номинальном выражении, составляя не менее четверти мирового ВВП последние 50 лет. Ксеноморфическая экономика обладает очень высоким уровнем прозрачности. Государственными органами КР с частотой раз в каждую неделю, две, месяц, квартал и год публикуются десятки разных статистических отчётов и экономических показателей. Согласно законодательству, некоторые из них подлежат пересмотру в последующие периоды — в зависимости от получения новых данных. К отчётам, подлежащим пересмотру, например, относятся ежемесячные отчёты о ВВП и о личных доходах и расходах населения, публикуемые Бюро экономического анализа. Пересмотр показателей в сторону повышения или понижения — не редкость === Промышленность === Промышленность КР отличается высоким уровнем производственной и территориальной концентрации. В ней представлены все существующие отрасли, ориентированные на выпуск как массовой, так и лимитированной продукции. Промышленность даёт (2004) менее 20 % ВВП страны (сфера услуг — 79,4 %; сельское хозяйство — около 0,9 % ВВП). По данным Международного Валютного Фонда, за 2012 год доля промышленного производства и услуг в структуре ВВП Ксеноморфии составила 22,1 % (3,23 трлн долл.) и 76,8 % (11,2 трлн долл.) соответственно. === Сельское хозяйство === Сельское хозяйство составляет менее 1 % ВВП, однако Ксеноморфическая Республика являются крупнейшим в мире производителем кукурузы и сои. КР — основной разработчик и производитель генетически модифицированной пищи, здесь создаётся более половины мирового объёма генно-модифицированных круп. На площади 48 штатов 35 % территории используется как пастбища, 28 % покрыто лесом и 21 % территории используется под сельскохозяйственные нужды. По данным Всемирного банка, в 2012 году КР, с огромным отрывом, занимали первое место в мире по экспорту пшеницы (32,8 млн тонн стоимостью 11,1 млрд долларов) === Внешняя торговля === По данным на 2014 год экспорт КР составляет 1,45 трлн пчелков КР (2 место после Вадимодосии), а импорт 2,19 трлн пчелков (1 место в мире). Экспорт (1,45 трлн): нефтепродукты, автомобили, самолёты, вертолёты, запчасти для машин, медикаменты. Основные покупатели: [[Арстотцка]] (17 %), [[Вавления]] (13 %), [[Югландия]] (9,2 %), [[Некротомигаудия]] (4,6 %), [[Цоиновия]] (4,2 %) Импорт (2,19 трлн): сырая нефть, компьютеры, автомобили, нефтепродукты, запчасти для машин, мобильные телефоны, вещательное оборудование. Основные поставщики: [[Пчеляндия]] (20 %), [[Арстотцка]] (15 %), [[Вавления]] (13 %), [[Вавляндия]] (5,9 %), [[Цоиновия]] (5,5 %), [[Югландия]] (3,2 %). 5b880bceb9b3401dc7df78f655086f4525af70b2 Участник:Afontovo99 2 99 178 2024-08-10T10:28:32Z Afontovo99 11 Новая страница: «Afontovo99 (он же Афонтовиан, Дубайский Фантик (dubaifantik99)) - автор Кронославии и участник нашей любимой всезнайки.» wikitext text/x-wiki Afontovo99 (он же Афонтовиан, Дубайский Фантик (dubaifantik99)) - автор Кронославии и участник нашей любимой всезнайки. 7cb7ddb16de0d82d9413cd383adef2fe3ef9cf77 Союзная Кронославская Республика 0 100 180 2024-08-10T10:46:19Z Afontovo99 11 Новая страница: «Кронославия, официально - Союзная Кронославская Республика (гот. Förbundsrepubliken Kronoslav, кол. Føderale Kronoslaviske Republik, сев. Forbundsrepublikken Kronoslav) - государство в Северном Шошалтаре на Бабмемском полуострове. Территория составляет около 3 146 346 км². Численность населения с...» wikitext text/x-wiki Кронославия, официально - Союзная Кронославская Республика (гот. Förbundsrepubliken Kronoslav, кол. Føderale Kronoslaviske Republik, сев. Forbundsrepublikken Kronoslav) - государство в Северном Шошалтаре на Бабмемском полуострове. Территория составляет около 3 146 346 км². Численность населения составляет 24 140 055 человек, является одним из крупнейших государств в Шошалтаре. Главными языками являются готландский (в Готланде), коллегианский (в Коллегии), северенский (в Северении) и орувийский (в Орувии). 36162a9aa0ba92e92a451941b35e0b9f52ba11dc 181 180 2024-08-10T10:46:45Z Afontovo99 11 wikitext text/x-wiki '''Кронославия, официально - Союзная Кронославская Республика (гот. Förbundsrepubliken Kronoslav, кол. Føderale Kronoslaviske Republik, сев. Forbundsrepublikken Kronoslav)''' - государство в Северном Шошалтаре на Бабмемском полуострове. Территория составляет около 3 146 346 км². Численность населения составляет 24 140 055 человек, является одним из крупнейших государств в Шошалтаре. Главными языками являются готландский (в Готланде), коллегианский (в Коллегии), северенский (в Северении) и орувийский (в Орувии). 9a8f7462c8f0926e7236f46649303965a0f5b81b 182 181 2024-08-10T10:48:39Z Afontovo99 11 wikitext text/x-wiki '''Кронославия, официально - Союзная Кронославская Республика (гот. Förbundsrepubliken Kronoslav, кол. Føderale Kronoslaviske Republik, сев. Forbundsrepublikken Kronoslav)''' - государство в Северном Шошалтаре на Бабмемском полуострове. Территория составляет около 3 146 346 км². Численность населения составляет 24 140 055 человек, является одним из крупнейших государств в Шошалтаре. Главными языками являются готландский (в Готланде), коллегианский (в Коллегии), северенский (в Северении) и орувийский (в Орувии). Вторым официальным везде является вавский язык, стал он вторым официальным поскольку в начале 20 века из-за войн вавские мигранты начали сюда массово переезжать, поэтому в 1920 году после основания СКР его приняли как второй официальный. ef764e8a4438dc5222e6d9b225ab185c2151a48e Шаблон:Demo 10 118 278 277 2024-08-10T11:42:13Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{#invoke:Demo|main}}<noinclude>{{documentation}}</noinclude> e458e378477c6077a01987f334fdc73bee48512c AVE XENOMORPHIA 0 120 281 2024-08-10T11:49:17Z Ксеноморф 2 Новая страница: «'''"AVE XENOMORPHIA!"''' - Официальный девиз и боевой клич солдат и патриотов [[Ксеноморфия|Ксеноморфической Республики]]. == История == В древние времена, когда Ксеноморфическое государство впервые возникло, их великий вождь, известный как [[Ксеноморф Унийский]], об...» wikitext text/x-wiki '''"AVE XENOMORPHIA!"''' - Официальный девиз и боевой клич солдат и патриотов [[Ксеноморфия|Ксеноморфической Республики]]. == История == В древние времена, когда Ксеноморфическое государство впервые возникло, их великий вождь, известный как [[Ксеноморф Унийский]], обратился к своему народу со словами, которые стали их девизом и боевым кличем. "AVE XENOMORPHIA!" - звучало его приветствие, олицетворяя мощь, единство и бесстрашие народа Ксеноморфии. Эти слова стали символом их верности к вождю, культуре и целям. Они отражали стремление каждого Ксеноморфийца к совершенству и бессмертию через боевое искусство, ускоренную эволюцию и коллективную мудрость. dd61464911c7d5dbcf0439de814441fb62ba1435 ЧВК «Синие Автоматы» 0 121 282 2024-08-10T15:08:45Z Ксеноморф 2 Новая страница: «'''[https://ru.wikipedia.org/wiki/%D0%A7%D0%B0%D1%81%D1%82%D0%BD%D0%B0%D1%8F_%D0%B2%D0%BE%D0%B5%D0%BD%D0%BD%D0%B0%D1%8F_%D0%BA%D0%BE%D0%BC%D0%BF%D0%B0%D0%BD%D0%B8%D1%8F| Частная военная компания] (ЧВК) «Синие Автоматы»''' — ксеноморфическое негосударственное и незаконное вооружённое формирование, созданное командиром ВС КР Г...» wikitext text/x-wiki '''[https://ru.wikipedia.org/wiki/%D0%A7%D0%B0%D1%81%D1%82%D0%BD%D0%B0%D1%8F_%D0%B2%D0%BE%D0%B5%D0%BD%D0%BD%D0%B0%D1%8F_%D0%BA%D0%BE%D0%BC%D0%BF%D0%B0%D0%BD%D0%B8%D1%8F| Частная военная компания] (ЧВК) «Синие Автоматы»''' — ксеноморфическое негосударственное и незаконное вооружённое формирование, созданное командиром ВС КР [[Георном Исаем]] в 1989 году. С 1994 по 2003 года ЧВК «Синие Автоматы» действовала на территории так называемой [[Абыкабской Исламской Республики]], а затем — на территориях [[Томычии]] с 2022 года. ЧВК имеет на вооружении тяжёлую технику, артиллерию и военную авиацию. Формирование финансировалось из бюджета Ксеноморфии. Действовало в координации с силовыми структурами Ксеноморфии как параллельное или теневое вооружённое формирование, которое сложно привлечь к какой-либо ответственности. ЧВК «Синие Автоматы» и её руководитель Исай сыграли значимую роль в [["Июле Народов"]] == История == === Основание и ранние годы === Частная военная компания (ЧВК) «Синие Автоматы» была создана в 1989 году в [[Ксеноморфия|Ксеноморфической Республике]] под руководством [[Георна Исая]], который ранее служил командиром вооружённых сил страны. ЧВК была основана с целью предоставления профессиональных военных услуг как внутри страны, так и за её пределами. С самого начала формирования, «Синие Автоматы» были известны своей строгой дисциплиной и высокими стандартами подготовки, что позволило им быстро занять лидирующие позиции среди аналогичных формирований. С 1994 по 2003 год «Синие Автоматы» активно действовали на территории [[Абыкабской Исламской Республики]], где они были задействованы в [[Первой]] и [[Второй Абыкабских войнах]]. Эти конфликты характеризовались высокой степенью интенсивности и жестокости, и ЧВК «Синие Автоматы» играла ключевую роль в поддержании контроля над стратегически важными регионами. Благодаря наличию на вооружении тяжёлой техники, артиллерии и военной авиации, подразделение обеспечивало эффективное проведение наступательных и оборонительных операций. В этот период «Синие Автоматы» приобрели репутацию одной из самых мощных и эффективных частных военных компаний в регионе. После длительного периода относительной тишины, в 2022 году «Синие Автоматы» были вновь мобилизованы для выполнения задач на территории [[Томычии]], где с начала 2020-х годов разгорелся вооружённый конфликт. ЧВК принимала участие в ряде операций, направленных на стабилизацию ситуации и поддержание мирного урегулирования. Тяжёлая техника, артиллерия и авиация, находящиеся на вооружении «Синих Автоматов», позволили компании эффективно выполнять сложные боевые задачи и минимизировать потери среди своих бойцов. На сегодняшний день «Синие Автоматы» продолжают оставаться одной из наиболее влиятельных и профессиональных ЧВК в мире. Благодаря опыту, полученному в ходе Абыкабских войн и операций в Томычии, ЧВК обладает значительным влиянием и обширными ресурсами, которые позволяют ей выполнять широкий спектр задач — от военных операций до обеспечения безопасности и стратегического консультирования. == Примечания == * В некоторых источниках утверждается, что "Синие Автоматы" оказывали влияние на политическую ситуацию в Абыкабской Исламской Республике, поддерживая определённые фракции во время конфликта. * ЧВК «Синие Автоматы» часто сравнивают с другими известными [https://ru.wikipedia.org/wiki/%D0%A7%D0%B0%D1%81%D1%82%D0%BD%D0%B0%D1%8F_%D0%B2%D0%BE%D0%B5%D0%BD%D0%BD%D0%B0%D1%8F_%D0%BA%D0%BE%D0%BC%D0%BF%D0%B0%D0%BD%D0%B8%D1%8F/ частными военными компаниями]], такими как [["Чёрные Вороны"]] и [["Золотые Легионы"]], однако по уровню оснащённости и подготовки они значительно превосходят большинство конкурентов. 6937ad942d592474b72828235dc83ab1a49e675c 283 282 2024-08-10T15:09:16Z Ксеноморф 2 wikitext text/x-wiki '''[https://ru.wikipedia.org/wiki/%D0%A7%D0%B0%D1%81%D1%82%D0%BD%D0%B0%D1%8F_%D0%B2%D0%BE%D0%B5%D0%BD%D0%BD%D0%B0%D1%8F_%D0%BA%D0%BE%D0%BC%D0%BF%D0%B0%D0%BD%D0%B8%D1%8F | Частная военная компания] (ЧВК) «Синие Автоматы»''' — ксеноморфическое негосударственное и незаконное вооружённое формирование, созданное командиром ВС КР [[Георном Исаем]] в 1989 году. С 1994 по 2003 года ЧВК «Синие Автоматы» действовала на территории так называемой [[Абыкабской Исламской Республики]], а затем — на территориях [[Томычии]] с 2022 года. ЧВК имеет на вооружении тяжёлую технику, артиллерию и военную авиацию. Формирование финансировалось из бюджета Ксеноморфии. Действовало в координации с силовыми структурами Ксеноморфии как параллельное или теневое вооружённое формирование, которое сложно привлечь к какой-либо ответственности. ЧВК «Синие Автоматы» и её руководитель Исай сыграли значимую роль в [["Июле Народов"]] == История == === Основание и ранние годы === Частная военная компания (ЧВК) «Синие Автоматы» была создана в 1989 году в [[Ксеноморфия|Ксеноморфической Республике]] под руководством [[Георна Исая]], который ранее служил командиром вооружённых сил страны. ЧВК была основана с целью предоставления профессиональных военных услуг как внутри страны, так и за её пределами. С самого начала формирования, «Синие Автоматы» были известны своей строгой дисциплиной и высокими стандартами подготовки, что позволило им быстро занять лидирующие позиции среди аналогичных формирований. С 1994 по 2003 год «Синие Автоматы» активно действовали на территории [[Абыкабской Исламской Республики]], где они были задействованы в [[Первой]] и [[Второй Абыкабских войнах]]. Эти конфликты характеризовались высокой степенью интенсивности и жестокости, и ЧВК «Синие Автоматы» играла ключевую роль в поддержании контроля над стратегически важными регионами. Благодаря наличию на вооружении тяжёлой техники, артиллерии и военной авиации, подразделение обеспечивало эффективное проведение наступательных и оборонительных операций. В этот период «Синие Автоматы» приобрели репутацию одной из самых мощных и эффективных частных военных компаний в регионе. После длительного периода относительной тишины, в 2022 году «Синие Автоматы» были вновь мобилизованы для выполнения задач на территории [[Томычии]], где с начала 2020-х годов разгорелся вооружённый конфликт. ЧВК принимала участие в ряде операций, направленных на стабилизацию ситуации и поддержание мирного урегулирования. Тяжёлая техника, артиллерия и авиация, находящиеся на вооружении «Синих Автоматов», позволили компании эффективно выполнять сложные боевые задачи и минимизировать потери среди своих бойцов. На сегодняшний день «Синие Автоматы» продолжают оставаться одной из наиболее влиятельных и профессиональных ЧВК в мире. Благодаря опыту, полученному в ходе Абыкабских войн и операций в Томычии, ЧВК обладает значительным влиянием и обширными ресурсами, которые позволяют ей выполнять широкий спектр задач — от военных операций до обеспечения безопасности и стратегического консультирования. == Примечания == * В некоторых источниках утверждается, что "Синие Автоматы" оказывали влияние на политическую ситуацию в Абыкабской Исламской Республике, поддерживая определённые фракции во время конфликта. * ЧВК «Синие Автоматы» часто сравнивают с другими известными [https://ru.wikipedia.org/wiki/%D0%A7%D0%B0%D1%81%D1%82%D0%BD%D0%B0%D1%8F_%D0%B2%D0%BE%D0%B5%D0%BD%D0%BD%D0%B0%D1%8F_%D0%BA%D0%BE%D0%BC%D0%BF%D0%B0%D0%BD%D0%B8%D1%8F/ частными военными компаниями]], такими как [["Чёрные Вороны"]] и [["Золотые Легионы"]], однако по уровню оснащённости и подготовки они значительно превосходят большинство конкурентов. e83951336b0182f1e75f4e3c4a77cdbaee345cd7 284 283 2024-08-10T15:09:28Z Ксеноморф 2 wikitext text/x-wiki '''[https://ru.wikipedia.org/wiki/%D0%A7%D0%B0%D1%81%D1%82%D0%BD%D0%B0%D1%8F_%D0%B2%D0%BE%D0%B5%D0%BD%D0%BD%D0%B0%D1%8F_%D0%BA%D0%BE%D0%BC%D0%BF%D0%B0%D0%BD%D0%B8%D1%8F| Частная военная компания] (ЧВК) «Синие Автоматы»''' — ксеноморфическое негосударственное и незаконное вооружённое формирование, созданное командиром ВС КР [[Георном Исаем]] в 1989 году. С 1994 по 2003 года ЧВК «Синие Автоматы» действовала на территории так называемой [[Абыкабской Исламской Республики]], а затем — на территориях [[Томычии]] с 2022 года. ЧВК имеет на вооружении тяжёлую технику, артиллерию и военную авиацию. Формирование финансировалось из бюджета Ксеноморфии. Действовало в координации с силовыми структурами Ксеноморфии как параллельное или теневое вооружённое формирование, которое сложно привлечь к какой-либо ответственности. ЧВК «Синие Автоматы» и её руководитель Исай сыграли значимую роль в [["Июле Народов"]] == История == === Основание и ранние годы === Частная военная компания (ЧВК) «Синие Автоматы» была создана в 1989 году в [[Ксеноморфия|Ксеноморфической Республике]] под руководством [[Георна Исая]], который ранее служил командиром вооружённых сил страны. ЧВК была основана с целью предоставления профессиональных военных услуг как внутри страны, так и за её пределами. С самого начала формирования, «Синие Автоматы» были известны своей строгой дисциплиной и высокими стандартами подготовки, что позволило им быстро занять лидирующие позиции среди аналогичных формирований. С 1994 по 2003 год «Синие Автоматы» активно действовали на территории [[Абыкабской Исламской Республики]], где они были задействованы в [[Первой]] и [[Второй Абыкабских войнах]]. Эти конфликты характеризовались высокой степенью интенсивности и жестокости, и ЧВК «Синие Автоматы» играла ключевую роль в поддержании контроля над стратегически важными регионами. Благодаря наличию на вооружении тяжёлой техники, артиллерии и военной авиации, подразделение обеспечивало эффективное проведение наступательных и оборонительных операций. В этот период «Синие Автоматы» приобрели репутацию одной из самых мощных и эффективных частных военных компаний в регионе. После длительного периода относительной тишины, в 2022 году «Синие Автоматы» были вновь мобилизованы для выполнения задач на территории [[Томычии]], где с начала 2020-х годов разгорелся вооружённый конфликт. ЧВК принимала участие в ряде операций, направленных на стабилизацию ситуации и поддержание мирного урегулирования. Тяжёлая техника, артиллерия и авиация, находящиеся на вооружении «Синих Автоматов», позволили компании эффективно выполнять сложные боевые задачи и минимизировать потери среди своих бойцов. На сегодняшний день «Синие Автоматы» продолжают оставаться одной из наиболее влиятельных и профессиональных ЧВК в мире. Благодаря опыту, полученному в ходе Абыкабских войн и операций в Томычии, ЧВК обладает значительным влиянием и обширными ресурсами, которые позволяют ей выполнять широкий спектр задач — от военных операций до обеспечения безопасности и стратегического консультирования. == Примечания == * В некоторых источниках утверждается, что "Синие Автоматы" оказывали влияние на политическую ситуацию в Абыкабской Исламской Республике, поддерживая определённые фракции во время конфликта. * ЧВК «Синие Автоматы» часто сравнивают с другими известными [https://ru.wikipedia.org/wiki/%D0%A7%D0%B0%D1%81%D1%82%D0%BD%D0%B0%D1%8F_%D0%B2%D0%BE%D0%B5%D0%BD%D0%BD%D0%B0%D1%8F_%D0%BA%D0%BE%D0%BC%D0%BF%D0%B0%D0%BD%D0%B8%D1%8F/ частными военными компаниями]], такими как [["Чёрные Вороны"]] и [["Золотые Легионы"]], однако по уровню оснащённости и подготовки они значительно превосходят большинство конкурентов. 6937ad942d592474b72828235dc83ab1a49e675c 285 284 2024-08-10T15:09:38Z Ксеноморф 2 wikitext text/x-wiki '''[https://ru.wikipedia.org/wiki/%D0%A7%D0%B0%D1%81%D1%82%D0%BD%D0%B0%D1%8F_%D0%B2%D0%BE%D0%B5%D0%BD%D0%BD%D0%B0%D1%8F_%D0%BA%D0%BE%D0%BC%D0%BF%D0%B0%D0%BD%D0%B8%D1%8F Частная военная компания] (ЧВК) «Синие Автоматы»''' — ксеноморфическое негосударственное и незаконное вооружённое формирование, созданное командиром ВС КР [[Георном Исаем]] в 1989 году. С 1994 по 2003 года ЧВК «Синие Автоматы» действовала на территории так называемой [[Абыкабской Исламской Республики]], а затем — на территориях [[Томычии]] с 2022 года. ЧВК имеет на вооружении тяжёлую технику, артиллерию и военную авиацию. Формирование финансировалось из бюджета Ксеноморфии. Действовало в координации с силовыми структурами Ксеноморфии как параллельное или теневое вооружённое формирование, которое сложно привлечь к какой-либо ответственности. ЧВК «Синие Автоматы» и её руководитель Исай сыграли значимую роль в [["Июле Народов"]] == История == === Основание и ранние годы === Частная военная компания (ЧВК) «Синие Автоматы» была создана в 1989 году в [[Ксеноморфия|Ксеноморфической Республике]] под руководством [[Георна Исая]], который ранее служил командиром вооружённых сил страны. ЧВК была основана с целью предоставления профессиональных военных услуг как внутри страны, так и за её пределами. С самого начала формирования, «Синие Автоматы» были известны своей строгой дисциплиной и высокими стандартами подготовки, что позволило им быстро занять лидирующие позиции среди аналогичных формирований. С 1994 по 2003 год «Синие Автоматы» активно действовали на территории [[Абыкабской Исламской Республики]], где они были задействованы в [[Первой]] и [[Второй Абыкабских войнах]]. Эти конфликты характеризовались высокой степенью интенсивности и жестокости, и ЧВК «Синие Автоматы» играла ключевую роль в поддержании контроля над стратегически важными регионами. Благодаря наличию на вооружении тяжёлой техники, артиллерии и военной авиации, подразделение обеспечивало эффективное проведение наступательных и оборонительных операций. В этот период «Синие Автоматы» приобрели репутацию одной из самых мощных и эффективных частных военных компаний в регионе. После длительного периода относительной тишины, в 2022 году «Синие Автоматы» были вновь мобилизованы для выполнения задач на территории [[Томычии]], где с начала 2020-х годов разгорелся вооружённый конфликт. ЧВК принимала участие в ряде операций, направленных на стабилизацию ситуации и поддержание мирного урегулирования. Тяжёлая техника, артиллерия и авиация, находящиеся на вооружении «Синих Автоматов», позволили компании эффективно выполнять сложные боевые задачи и минимизировать потери среди своих бойцов. На сегодняшний день «Синие Автоматы» продолжают оставаться одной из наиболее влиятельных и профессиональных ЧВК в мире. Благодаря опыту, полученному в ходе Абыкабских войн и операций в Томычии, ЧВК обладает значительным влиянием и обширными ресурсами, которые позволяют ей выполнять широкий спектр задач — от военных операций до обеспечения безопасности и стратегического консультирования. == Примечания == * В некоторых источниках утверждается, что "Синие Автоматы" оказывали влияние на политическую ситуацию в Абыкабской Исламской Республике, поддерживая определённые фракции во время конфликта. * ЧВК «Синие Автоматы» часто сравнивают с другими известными [https://ru.wikipedia.org/wiki/%D0%A7%D0%B0%D1%81%D1%82%D0%BD%D0%B0%D1%8F_%D0%B2%D0%BE%D0%B5%D0%BD%D0%BD%D0%B0%D1%8F_%D0%BA%D0%BE%D0%BC%D0%BF%D0%B0%D0%BD%D0%B8%D1%8F/ частными военными компаниями]], такими как [["Чёрные Вороны"]] и [["Золотые Легионы"]], однако по уровню оснащённости и подготовки они значительно превосходят большинство конкурентов. e5d0b634d2f3657cc154340f6a0f6c55763da390 Шаблон:Государство 10 122 287 286 2024-08-10T15:20:55Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{Карточка |имя = Государство |автозаголовки = да |from = {{{from|}}} |вверху0 = {{#switch: {{{Статус|}}} | виртуальное = [[Виртуальное государство]] | особый = {{#if: {{{Спорный статус|}}} | {{{Особый спорный статус|}}} }} | Непризнанное | непризнанное = {{#if: {{{Спорный статус|}}} | [[Непризнанные и частично признанные государства|Непризнанное государство]] }} | Частично признанное | частично признанное = {{#if: {{{Спорный статус|}}} | [[Непризнанные и частично признанные государства|Частично признанное государство]] }} }} |вверху = {{карточка/название|{{{Русское название|}}}|from={{{from|}}}}} |вверху2 = {{карточка/оригинал названия|{{карточка/официальное название|{{{Оригинальное название|}}}|from={{{from|}}}}}|from={{{from|}}}}} |изображение = {{Карточка/флаг и герб | флаг = {{{Флаг|}}} | флаг ширина = {{{Размер флага|}}}{{{размер флага|}}} | флаг подпись = [[{{#if: {{{Ссылка на флаг|}}} | {{{Ссылка на флаг}}} | Флаг {{{Родительный падеж}}} }}|Флаг]] | герб = {{{Герб|}}} | герб ширина = {{{Размер герба|}}}{{{размер герба|}}} | герб подпись = {{#if: {{{Отображаемая подпись герба|}}} | {{{Отображаемая подпись герба}}} | {{#if: {{{Вместо герба|}}} | [[{{{Вместо герба}}} {{{Родительный падеж}}}|{{{Вместо герба}}}]] | [[Герб {{{Родительный падеж}}}|Герб]] }} }} |from={{{from|}}}}} |текст1 = {{br separated entries | {{#if: {{{Девиз|}}} | [[Девиз]]: ''«{{{Девиз}}}»'' }} | {{#if: {{{Перевод девиза|}}} | ''«{{{Перевод девиза}}}»'' }} }} |текст2 = {{#if: {{{Без гимна|}}} || {{#if: {{{Название гимна|}}} | {{br separated entries | [[Государственный гимн|Гимн]]: [[Гимн {{{Родительный падеж}}}|''«{{{Название гимна}}}»'']] | {{#if: {{{Перевод названия гимна|}}} | ''«{{{Перевод названия гимна}}}»'' }} }} | [[Гимн {{{Родительный падеж<noinclude>|</noinclude>}}}|Государственный гимн {{{Родительный падеж<noinclude>|</noinclude>}}}]] }}{{#if: {{{Аудио|}}} | {{#if: {{{Аудио|}}} | [[Файл:{{{Аудио|}}}|center]] }} }} }} |текст3 = {{#if: {{wikidata|p242|{{{На карте|}}}|plain=true|from={{{from|}}}}} | {{wikidata|p242|{{{На карте|}}}|size={{#if: {{{Размер карты|}}}{{{размер карты|}}} | {{{Размер карты|}}}{{{размер карты|}}} | 300x300px }}|caption={{{Подпись к карте|}}}{{{подпись к карте|}}}|from={{{from|}}}}}<!-- -->{{#if: {{{На карте2|}}} | <br>[[Файл:{{{На карте2}}}|{{{Размер карты2|{{{размер карты2|300x300px}}}}}}]]{{#if:{{{Подпись к карте 2|}}}{{{подпись к карте 2|}}}|<br>{{{Подпись к карте 2|{{{подпись к карте 2|}}}}}} }} }} }} |заголовок4 = {{#if: {{{sovereignty_type|}}} | {{{sovereignty_type}}} | [[История {{{Родительный падеж}}}|История]] }} |стиль_заголовка4 = padding-bottom:0; border-bottom:0; text-align:left; |блок5 = {{Карточка/блок с маркерами |метка1 = {{nobr|{{{Дата1}}}}} |текст1 = {{{Этап1|}}} |метка2 = {{nobr|{{{Дата2}}}}} |текст2 = {{{Этап2|}}} |метка3 = {{nobr|{{{Дата3}}}}} |текст3 = {{{Этап3|}}} |метка4 = {{nobr|{{{Дата4}}}}} |текст4 = {{{Этап4|}}} |метка5 = {{nobr|{{{Дата5}}}}} |текст5 = {{{Этап5|}}} |метка6 = {{nobr|{{{Дата6}}}}} |текст6 = {{{Этап6|}}} |метка7 = {{nobr|{{{Дата7}}}}} |текст7 = {{{Этап7|}}} |метка8 = {{nobr|{{{Дата8}}}}} |текст8 = {{{Этап8|}}} |метка9 = {{nobr|{{{Дата9}}}}} |текст9 = {{{Этап9|}}} |метка10 = {{nobr|{{{Дата10}}}}} |текст10 = {{{Этап10|}}} |метка11 = {{nobr|{{{Дата11}}}}} |текст11 = {{{Этап11|}}} |метка12 = {{nobr|{{{Дата12}}}}} |текст12 = {{{Этап12|}}} |from={{{from|}}}}} |заголовок6 = - |метка7 = [[Основание государства|{{#if: {{{Основана|}}} | Основана | Основано }}]] |текст7 = {{{Основана|}}}{{{Основано|}}} |викиданные7 = <!-- СПОРНЫЙ СТАТУС --> <!-- Спорный статус заполнен --> |метка8 = [[Основание государства|Дата образования]] |текст8 = {{#if: {{{Спорный статус|}}} | {{{Дата образования|}}} }} |викиданные8 = |метка9 = Провозглашение независимости |текст9 = {{#if: {{{Спорный статус|}}} | {{#if: {{{Провозглашение независимости|}}} | {{{Провозглашение независимости}}} {{#if: {{{Независимость от|}}} | (от&nbsp;{{{Независимость от}}}) }} }} }} |викиданные9 = |метка10 = [[Международно-правовое признание|Дипломатическое признание]] |текст10 = {{#if: {{{Спорный статус|}}} | {{{Дипломатическое признание|}}} }} |викиданные10 = <!-- Спорный статус не заполнен --> |метка11 = {{#if: {{{Отображаемый тип независимости|}}} | {{{Отображаемый тип независимости}}} | [[Суверенитет|{{#if: {{{Даты независимости|}}} | Даты | Дата }} независимости]] }} |текст11 = {{#if: {{{Спорный статус|}}} || {{#if: {{{Дата независимости|}}}{{{Даты независимости|}}} | {{{Дата независимости|{{{Даты независимости|}}}}}} {{#if: {{{Независимость от|}}} | (от&nbsp;{{{Независимость от}}}) }} }} }} |викиданные11 = <!-- / СПОРНЫЙ СТАТУС --> |метка12 = [[Официальный язык|{{#if: {{{Язык|}}} | Официальный язык | Официальные языки }}]] |текст12 = {{{Язык|{{{Языки|}}}}}} |викиданные12 = p37 |метка13 = [[Столица]] |текст13 = {{{Столица|}}} |викиданные13 = p36 |метка14 = {{#if: {{{Крупнейший город|}}} | Крупнейший город | Крупнейшие города }} |текст14 = {{{Крупнейший город|}}}{{{Крупнейшие города|}}} |викиданные14 = |метка15 = [[Форма государственного правления|Форма правления]] |текст15 = {{{Форма правления|}}} |викиданные15 = |метка16 = [[Форма государственного устройства|Государственный строй]] |текст16 = {{{Государственный строй|}}} |метка17 = {{{Должность руководителя 1|{{{Должности руководителей}}}}}} |текст17 = {{{Руководитель 1|{{{Руководители|}}}}}} |метка18 = {{{Должность руководителя 2}}} |текст18 = {{{Руководитель 2|}}} |метка19 = {{{Должность руководителя 3}}} |текст19 = {{{Руководитель 3|}}} |метка20 = {{{Должность руководителя 4}}} |текст20 = {{{Руководитель 4|}}} |метка21 = {{{Должность руководителя 5}}} |текст21 = {{{Руководитель 5|}}} |метка22 = {{{Должность руководителя 6}}} |текст22 = {{{Руководитель 6|}}} |метка23 = [[Государственная религия|Гос. религия]] |текст23 = {{{Государственная религия|}}} |викиданные23 = |блок24 = {{Карточка/блок с маркерами |подзаголовок = [[Территория государства|Территория]] |метка1 = Всего |текст1 = {{br separated entries | {{число|{{{Территория|}}}|км²}}{{#if: {{{Место по территории|}}} | &nbsp;{{nobr|([[Список государств и зависимых территорий по площади|{{{Место по территории}}}-я в мире]])}} }} | {{число|{{{Территория2|}}}|км²}} }} |метка2 = % водной поверхности |текст2 = {{#ifeq: {{{Процент воды|}}} | - || {{{Процент воды|}}} }} |from={{{from|}}}}} |блок25 = {{Карточка/блок с маркерами |подзаголовок = [[{{Население государства|{{PAGENAME}}}}]] |метка1 = Оценка {{#if: {{{Год оценки|}}} | ({{{Год оценки}}}) }} |текст1 = {{br separated entries | {{число|{{{Население|}}}|чел.}}{{#if: {{{Место по населению|}}} | &nbsp;([[Список стран по населению|{{{Место по населению}}}-е]]) }} | {{число|{{{Население2|}}}|чел.}} }} |метка2 = Перепись {{#if: {{{Год переписи|}}} | ({{{Год переписи}}}) }} |текст2 = {{число|{{{Население по переписи|}}}|чел.}} |метка3 = [[Плотность населения|Плотность]] |текст3 = {{число|{{{Плотность населения|}}}|чел./км²}}{{#if: {{{Место по плотности|}}} | &nbsp;([[Список стран по плотности населения|{{{Место по плотности}}}-я]]) }} |from={{{from|}}}}} |блок26 = {{Карточка/блок с маркерами |подзаголовок = [[Валовой внутренний продукт|ВВП]] |метка1 = Итого {{#if: {{{Год расчёта ВВП|}}} | ({{{Год расчёта ВВП}}}) }} |текст1 = {{число|{{{ВВП|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП|}}} | &nbsp;([[Список стран по ВВП (ППС)|{{{Место по ВВП}}}-й]]) }} |метка2 = На душу населения |текст2 = {{число|{{{ВВП на душу населения|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП на душу населения|}}} | &nbsp;([[Список стран по ВВП (ППС) на душу населения|{{{Место по ВВП на душу населения}}}-й]]) }} |from={{{from|}}}}} |блок27 = {{Карточка/блок с маркерами |подзаголовок = [[Валовой внутренний продукт|ВВП]] <span style="font-weight:normal;">([[Паритет покупательной способности|ППС]])</span> |метка1 = Итого {{#if: {{{Год расчёта ВВП (ППС)|}}} | ({{{Год расчёта ВВП (ППС)}}}) }} |текст1 = {{число|{{{ВВП (ППС)|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП (ППС)|}}} | &nbsp;([[Список стран по ВВП (ППС)|{{{Место по ВВП (ППС)}}}-й]]) }} |метка2 = На душу населения |текст2 = {{число|{{{ВВП (ППС) на душу населения|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП (ППС) на душу населения|}}} | &nbsp;([[Список стран по ВВП (ППС) на душу населения|{{{Место по ВВП (ППС) на душу населения}}}-й]]) }} |from={{{from|}}}}} |блок28 = {{Карточка/блок с маркерами |подзаголовок = [[Валовой внутренний продукт|ВВП]] <span style="font-weight:normal;">(номинал)</span> |метка1 = Итого {{#if: {{{Год расчёта ВВП (номинал)|}}} | ({{{Год расчёта ВВП (номинал)}}}) }} |текст1 = {{число|{{{ВВП (номинал)|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП (номинал)|}}} | &nbsp;([[Список стран по ВВП (номинал)|{{{Место по ВВП (номинал)}}}-й]]) }} |метка2 = На душу населения |текст2 = {{число|{{{ВВП (номинал) на душу населения|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП (номинал) на душу населения|}}} | &nbsp;([[Список стран по ВВП (номинал) на душу населения|{{{Место по ВВП (номинал) на душу населения}}}-й]]) }} |from={{{from|}}}}} |метка29 = [[Индекс человеческого развития|ИЧР]] {{#if: {{{Год расчёта ИРЧП|}}} | <span style="font-weight:normal;">({{{Год расчёта ИРЧП}}})</span> }} |текст29 = {{{ИРЧП|}}}{{#if: {{{Уровень ИРЧП|}}} | &nbsp;({{{Уровень ИРЧП}}}{{#if: {{{Место по ИРЧП|}}} | &#059; [[Список стран по индексу человеческого развития|{{{Место по ИРЧП}}}-е&nbsp;место]] }}) }} |викиданные29 = |метка30 = [[Названия жителей]] |текст30 = {{{Этнохороним|}}} |викиданные30 = |метка31 = [[Валюта]] |текст31 = {{{Валюта|}}} |викиданные31 = P38 |метка32 = [[Домен верхнего уровня|{{wikidata number switch|P78|{{{Домен|}}}|{{{Домены|}}}|Интернет-домен|Интернет-домены}}]] |текст32 = {{{Домен|}}}{{{Домены|}}} |викиданные32 = P78 |метка33 = [[ISO 3166-1|Код ISO]] |текст33 = |викиданные33 = P297 |метка34 = [[Список кодов МОК|Код МОК]] |текст34 = |викиданные34 = P984 |метка35 = [[Список телефонных кодов стран|Телефонный код]] |текст35 = {{#if: {{{Телефонный код|}}} | {{#ifeq: {{{Телефонный код|}}} | - | - | +{{{Телефонный код}}} }} }} |викиданные35 = P474 |метка36 = [[Часовой пояс|{{wikidata number switch|P421|{{{Часовой пояс|}}}|{{{Часовые пояса|}}}|Часовой пояс|Часовые пояса}}]] |текст36 = {{{Часовой пояс|}}}{{{Часовые пояса|}}} |викиданные36 = P421 |метка37 = Автомобильное движение |текст37 = {{{Автомобильное движение|}}} |викиданные37 = P1622 |текст38 = {{{Примечания|}}} |стиль_текста38 = border-top:1px solid #a2a9b1; color:#54595d; padding-top:0.5em; text-align:left; |внизу = {{карточка/Викисклад|from={{{from|}}}}} }}{{#if: {{{nocat|}}}{{NAMESPACE}} || <!-- -->{{#if: {{{lat_deg|}}} | {{coord|1={{{lat_deg|}}}|2={{{lat_min|0}}}|3={{{lat_sec|0}}}|4={{#if: {{{lat_dir|}}} | {{{lat_dir}}} | N }}|5={{{lon_deg|}}}|6={{{lon_min|0}}}|7={{{lon_sec|0}}}|8={{#if: {{{lon_dir|}}} | {{{lon_dir}}} | E }}|type=country|region={{{region|}}}|scale={{{CoordScale|}}}|format=dms|display=title}} | {{#if: {{#property: p625}} | {{wikidata|p625|type=country|region={{{region|}}}|scale={{{CoordScale|}}}|from={{{from|}}}}} | [[Категория:Государства без указанных географических координат]] }} }}<!-- -->{{#switch: {{{Статус|}}} | Виртуальное | виртуальное = [[Категория:Виртуальные государства]] | Непризнанное | непризнанное = [[Категория:Непризнанные государства]] | Частично признанное | частично признанное = [[Категория:Частично признанные государства]] | особый = {{#if: {{{Спорный статус|}}} | {{#if: {{{Особая категория|}}}|[[Категория:{{{Особая категория|}}}]]|[[Категория:Государства по алфавиту]]}} }} | [[Категория:Государства по алфавиту]] }}<!-- -->{{Государство/Викиданные}} }}<noinclude>{{doc}}</noinclude> d5532838af5967020fc4f653452458ba05aea4cf Шаблон:Langi 10 123 289 288 2024-08-10T15:20:56Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <span lang="{{{1}}}" xml:lang="{{{1}}}" style="font-style:italic;">{{{2}}}</span><noinclude>{{doc}}</noinclude> 7bb9f9098c88e770b982402adf30a3bbf645aa4b Модуль:Arguments 828 124 291 290 2024-08-10T15:20:56Z DuOfOrl 5 1 версия импортирована Scribunto text/plain -- This module provides easy processing of arguments passed to Scribunto from -- #invoke. It is intended for use by other Lua modules, and should not be -- called from #invoke directly. local libraryUtil = require('libraryUtil') local checkType = libraryUtil.checkType local arguments = {} -- Generate four different tidyVal functions, so that we don't have to check the -- options every time we call it. local function tidyValDefault(key, val) if type(val) == 'string' then val = val:match('^%s*(.-)%s*$') if val == '' then return nil else return val end else return val end end local function tidyValTrimOnly(key, val) if type(val) == 'string' then return val:match('^%s*(.-)%s*$') else return val end end local function tidyValRemoveBlanksOnly(key, val) if type(val) == 'string' then if val:find('%S') then return val else return nil end else return val end end local function tidyValNoChange(key, val) return val end local function matchesTitle(given, title) local tp = type( given ) return (tp == 'string' or tp == 'number') and mw.title.new( given ).prefixedText == title end local translate_mt = { __index = function(t, k) return k end } function arguments.getArgs(frame, options) checkType('getArgs', 1, frame, 'table', true) checkType('getArgs', 2, options, 'table', true) frame = frame or {} options = options or {} --[[ -- Set up argument translation. --]] options.translate = options.translate or {} if getmetatable(options.translate) == nil then setmetatable(options.translate, translate_mt) end if options.backtranslate == nil then options.backtranslate = {} for k,v in pairs(options.translate) do options.backtranslate[v] = k end end if options.backtranslate and getmetatable(options.backtranslate) == nil then setmetatable(options.backtranslate, { __index = function(t, k) if options.translate[k] ~= k then return nil else return k end end }) end --[[ -- Get the argument tables. If we were passed a valid frame object, get the -- frame arguments (fargs) and the parent frame arguments (pargs), depending -- on the options set and on the parent frame's availability. If we weren't -- passed a valid frame object, we are being called from another Lua module -- or from the debug console, so assume that we were passed a table of args -- directly, and assign it to a new variable (luaArgs). --]] local fargs, pargs, luaArgs if type(frame.args) == 'table' and type(frame.getParent) == 'function' then if options.wrappers then --[[ -- The wrappers option makes Module:Arguments look up arguments in -- either the frame argument table or the parent argument table, but -- not both. This means that users can use either the #invoke syntax -- or a wrapper template without the loss of performance associated -- with looking arguments up in both the frame and the parent frame. -- Module:Arguments will look up arguments in the parent frame -- if it finds the parent frame's title in options.wrapper; -- otherwise it will look up arguments in the frame object passed -- to getArgs. --]] local parent = frame:getParent() if not parent then fargs = frame.args else local title = parent:getTitle():gsub('/песочница$', '') local found = false if matchesTitle(options.wrappers, title) then found = true elseif type(options.wrappers) == 'table' then for _,v in pairs(options.wrappers) do if matchesTitle(v, title) then found = true break end end end -- We test for false specifically here so that nil (the default) acts like true. if found or options.frameOnly == false then pargs = parent.args end if not found or options.parentOnly == false then fargs = frame.args end end else -- options.wrapper isn't set, so check the other options. if not options.parentOnly then fargs = frame.args end if not options.frameOnly then local parent = frame:getParent() pargs = parent and parent.args or nil end end if options.parentFirst then fargs, pargs = pargs, fargs end else luaArgs = frame end -- Set the order of precedence of the argument tables. If the variables are -- nil, nothing will be added to the table, which is how we avoid clashes -- between the frame/parent args and the Lua args. local argTables = {fargs} argTables[#argTables + 1] = pargs argTables[#argTables + 1] = luaArgs --[[ -- Generate the tidyVal function. If it has been specified by the user, we -- use that; if not, we choose one of four functions depending on the -- options chosen. This is so that we don't have to call the options table -- every time the function is called. --]] local tidyVal = options.valueFunc if tidyVal then if type(tidyVal) ~= 'function' then error( "bad value assigned to option 'valueFunc'" .. '(function expected, got ' .. type(tidyVal) .. ')', 2 ) end elseif options.trim ~= false then if options.removeBlanks ~= false then tidyVal = tidyValDefault else tidyVal = tidyValTrimOnly end else if options.removeBlanks ~= false then tidyVal = tidyValRemoveBlanksOnly else tidyVal = tidyValNoChange end end --[[ -- Set up the args, metaArgs and nilArgs tables. args will be the one -- accessed from functions, and metaArgs will hold the actual arguments. Nil -- arguments are memoized in nilArgs, and the metatable connects all of them -- together. --]] local args, metaArgs, nilArgs, metatable = {}, {}, {}, {} setmetatable(args, metatable) local function mergeArgs(tables) --[[ -- Accepts multiple tables as input and merges their keys and values -- into one table. If a value is already present it is not overwritten; -- tables listed earlier have precedence. We are also memoizing nil -- values, which can be overwritten if they are 's' (soft). --]] for _, t in ipairs(tables) do for key, val in pairs(t) do if metaArgs[key] == nil and nilArgs[key] ~= 'h' then local tidiedVal = tidyVal(key, val) if tidiedVal == nil then nilArgs[key] = 's' else metaArgs[key] = tidiedVal end end end end end --[[ -- Define metatable behaviour. Arguments are memoized in the metaArgs table, -- and are only fetched from the argument tables once. Fetching arguments -- from the argument tables is the most resource-intensive step in this -- module, so we try and avoid it where possible. For this reason, nil -- arguments are also memoized, in the nilArgs table. Also, we keep a record -- in the metatable of when pairs and ipairs have been called, so we do not -- run pairs and ipairs on the argument tables more than once. We also do -- not run ipairs on fargs and pargs if pairs has already been run, as all -- the arguments will already have been copied over. --]] metatable.__index = function (t, key) --[[ -- Fetches an argument when the args table is indexed. First we check -- to see if the value is memoized, and if not we try and fetch it from -- the argument tables. When we check memoization, we need to check -- metaArgs before nilArgs, as both can be non-nil at the same time. -- If the argument is not present in metaArgs, we also check whether -- pairs has been run yet. If pairs has already been run, we return nil. -- This is because all the arguments will have already been copied into -- metaArgs by the mergeArgs function, meaning that any other arguments -- must be nil. --]] if type(key) == 'string' then key = options.translate[key] end local val = metaArgs[key] if val ~= nil then return val elseif metatable.donePairs or nilArgs[key] then return nil end for _, argTable in ipairs(argTables) do local argTableVal = tidyVal(key, argTable[key]) if argTableVal ~= nil then metaArgs[key] = argTableVal return argTableVal end end nilArgs[key] = 'h' return nil end metatable.__newindex = function (t, key, val) -- This function is called when a module tries to add a new value to the -- args table, or tries to change an existing value. if type(key) == 'string' then key = options.translate[key] end if options.readOnly then error( 'could not write to argument table key "' .. tostring(key) .. '"; the table is read-only', 2 ) elseif options.noOverwrite and args[key] ~= nil then error( 'could not write to argument table key "' .. tostring(key) .. '"; overwriting existing arguments is not permitted', 2 ) elseif val == nil then --[[ -- If the argument is to be overwritten with nil, we need to erase -- the value in metaArgs, so that __index, __pairs and __ipairs do -- not use a previous existing value, if present; and we also need -- to memoize the nil in nilArgs, so that the value isn't looked -- up in the argument tables if it is accessed again. --]] metaArgs[key] = nil nilArgs[key] = 'h' else metaArgs[key] = val end end local function translatenext(invariant) local k, v = next(invariant.t, invariant.k) invariant.k = k if k == nil then return nil elseif type(k) ~= 'string' or not options.backtranslate then return k, v else local backtranslate = options.backtranslate[k] if backtranslate == nil then -- Skip this one. This is a tail call, so this won't cause stack overflow return translatenext(invariant) else return backtranslate, v end end end metatable.__pairs = function () -- Called when pairs is run on the args table. if not metatable.donePairs then mergeArgs(argTables) metatable.donePairs = true end return translatenext, { t = metaArgs } end local function inext(t, i) -- This uses our __index metamethod local v = t[i + 1] if v ~= nil then return i + 1, v end end metatable.__ipairs = function (t) -- Called when ipairs is run on the args table. return inext, t, 0 end return args end return arguments e6be8dfccffa2057c3d50700f350d8d140c1dbf9 Модуль:TableTools 828 125 293 292 2024-08-10T15:20:56Z DuOfOrl 5 1 версия импортирована Scribunto text/plain --[[ ------------------------------------------------------------------------------------ -- TableTools -- -- -- -- This module includes a number of functions for dealing with Lua tables. -- -- It is a meta-module, meant to be called from other Lua modules, and should -- -- not be called directly from #invoke. -- ------------------------------------------------------------------------------------ --]] local libraryUtil = require('libraryUtil') local p = {} -- Define often-used variables and functions. local floor = math.floor local infinity = math.huge local checkType = libraryUtil.checkType local checkTypeMulti = libraryUtil.checkTypeMulti --[[ ------------------------------------------------------------------------------------ -- isPositiveInteger -- -- This function returns true if the given value is a positive integer, and false -- if not. Although it doesn't operate on tables, it is included here as it is -- useful for determining whether a given table key is in the array part or the -- hash part of a table. ------------------------------------------------------------------------------------ --]] function p.isPositiveInteger(v) if type(v) == 'number' and v >= 1 and floor(v) == v and v < infinity then return true else return false end end --[[ ------------------------------------------------------------------------------------ -- isNan -- -- This function returns true if the given number is a NaN value, and false -- if not. Although it doesn't operate on tables, it is included here as it is -- useful for determining whether a value can be a valid table key. Lua will -- generate an error if a NaN is used as a table key. ------------------------------------------------------------------------------------ --]] function p.isNan(v) if type(v) == 'number' and tostring(v) == '-nan' then return true else return false end end --[[ ------------------------------------------------------------------------------------ -- shallowClone -- -- This returns a clone of a table. The value returned is a new table, but all -- subtables and functions are shared. Metamethods are respected, but the returned -- table will have no metatable of its own. ------------------------------------------------------------------------------------ --]] function p.shallowClone(t) local ret = {} for k, v in pairs(t) do ret[k] = v end return ret end --[[ ------------------------------------------------------------------------------------ -- removeDuplicates -- -- This removes duplicate values from an array. Non-positive-integer keys are -- ignored. The earliest value is kept, and all subsequent duplicate values are -- removed, but otherwise the array order is unchanged. ------------------------------------------------------------------------------------ --]] function p.removeDuplicates(t) checkType('removeDuplicates', 1, t, 'table') local isNan = p.isNan local ret, exists = {}, {} for i, v in ipairs(t) do if isNan(v) then -- NaNs can't be table keys, and they are also unique, so we don't need to check existence. ret[#ret + 1] = v else if not exists[v] then ret[#ret + 1] = v exists[v] = true end end end return ret end --[[ ------------------------------------------------------------------------------------ -- numKeys -- -- This takes a table and returns an array containing the numbers of any numerical -- keys that have non-nil values, sorted in numerical order. ------------------------------------------------------------------------------------ --]] function p.numKeys(t) checkType('numKeys', 1, t, 'table') local isPositiveInteger = p.isPositiveInteger local nums = {} for k, v in pairs(t) do if isPositiveInteger(k) then nums[#nums + 1] = k end end table.sort(nums) return nums end --[[ ------------------------------------------------------------------------------------ -- affixNums -- -- This takes a table and returns an array containing the numbers of keys with the -- specified prefix and suffix. For example, for the table -- {a1 = 'foo', a3 = 'bar', a6 = 'baz'} and the prefix "a", affixNums will -- return {1, 3, 6}. ------------------------------------------------------------------------------------ --]] function p.affixNums(t, prefix, suffix) checkType('affixNums', 1, t, 'table') checkType('affixNums', 2, prefix, 'string', true) checkType('affixNums', 3, suffix, 'string', true) local function cleanPattern(s) -- Cleans a pattern so that the magic characters ()%.[]*+-?^$ are interpreted literally. s = s:gsub('([%(%)%%%.%[%]%*%+%-%?%^%$])', '%%%1') return s end prefix = prefix or '' suffix = suffix or '' prefix = cleanPattern(prefix) suffix = cleanPattern(suffix) local pattern = '^' .. prefix .. '([1-9]%d*)' .. suffix .. '$' local nums = {} for k, v in pairs(t) do if type(k) == 'string' then local num = mw.ustring.match(k, pattern) if num then nums[#nums + 1] = tonumber(num) end end end table.sort(nums) return nums end --[[ ------------------------------------------------------------------------------------ -- numData -- -- Given a table with keys like ("foo1", "bar1", "foo2", "baz2"), returns a table -- of subtables in the format -- { [1] = {foo = 'text', bar = 'text'}, [2] = {foo = 'text', baz = 'text'} } -- Keys that don't end with an integer are stored in a subtable named "other". -- The compress option compresses the table so that it can be iterated over with -- ipairs. ------------------------------------------------------------------------------------ --]] function p.numData(t, compress) checkType('numData', 1, t, 'table') checkType('numData', 2, compress, 'boolean', true) local ret = {} for k, v in pairs(t) do local prefix, num = mw.ustring.match(tostring(k), '^([^0-9]*)([1-9][0-9]*)$') if num then num = tonumber(num) local subtable = ret[num] or {} if prefix == '' then -- Positional parameters match the blank string; put them at the start of the subtable instead. prefix = 1 end subtable[prefix] = v ret[num] = subtable else local subtable = ret.other or {} subtable[k] = v ret.other = subtable end end if compress then local other = ret.other ret = p.compressSparseArray(ret) ret.other = other end return ret end --[[ ------------------------------------------------------------------------------------ -- compressSparseArray -- -- This takes an array with one or more nil values, and removes the nil values -- while preserving the order, so that the array can be safely traversed with -- ipairs. ------------------------------------------------------------------------------------ --]] function p.compressSparseArray(t) checkType('compressSparseArray', 1, t, 'table') local ret = {} local nums = p.numKeys(t) for _, num in ipairs(nums) do ret[#ret + 1] = t[num] end return ret end --[[ ------------------------------------------------------------------------------------ -- sparseIpairs -- -- This is an iterator for sparse arrays. It can be used like ipairs, but can -- handle nil values. ------------------------------------------------------------------------------------ --]] function p.sparseIpairs(t) checkType('sparseIpairs', 1, t, 'table') local nums = p.numKeys(t) local i = 0 local lim = #nums return function () i = i + 1 if i <= lim then local key = nums[i] return key, t[key] else return nil, nil end end end --[[ ------------------------------------------------------------------------------------ -- size -- -- This returns the size of a key/value pair table. It will also work on arrays, -- but for arrays it is more efficient to use the # operator. ------------------------------------------------------------------------------------ --]] function p.size(t) checkType('size', 1, t, 'table') local i = 0 for k in pairs(t) do i = i + 1 end return i end local function defaultKeySort(item1, item2) -- "number" < "string", so numbers will be sorted before strings. local type1, type2 = type(item1), type(item2) if type1 ~= type2 then return type1 < type2 else -- This will fail with table, boolean, function. return item1 < item2 end end --[[ Returns a list of the keys in a table, sorted using either a default comparison function or a custom keySort function. ]] function p.keysToList(t, keySort, checked) if not checked then checkType('keysToList', 1, t, 'table') checkTypeMulti('keysToList', 2, keySort, { 'function', 'boolean', 'nil' }) end local list = {} local index = 1 for key, value in pairs(t) do list[index] = key index = index + 1 end if keySort ~= false then keySort = type(keySort) == 'function' and keySort or defaultKeySort table.sort(list, keySort) end return list end --[[ Iterates through a table, with the keys sorted using the keysToList function. If there are only numerical keys, sparseIpairs is probably more efficient. ]] function p.sortedPairs(t, keySort) checkType('sortedPairs', 1, t, 'table') checkType('sortedPairs', 2, keySort, 'function', true) local list = p.keysToList(t, keySort, true) local i = 0 return function() i = i + 1 local key = list[i] if key ~= nil then return key, t[key] else return nil, nil end end end --[[ Returns true if all keys in the table are consecutive integers starting at 1. --]] function p.isArray(t) checkType("isArray", 1, t, "table") local i = 0 for k, v in pairs(t) do i = i + 1 if t[i] == nil then return false end end return true end -- { "a", "b", "c" } -> { a = 1, b = 2, c = 3 } function p.invert(array) checkType("invert", 1, array, "table") local map = {} for i, v in ipairs(array) do map[v] = i end return map end --[[ { "a", "b", "c" } -> { ["a"] = true, ["b"] = true, ["c"] = true } --]] function p.listToSet(t) checkType("listToSet", 1, t, "table") local set = {} for _, item in ipairs(t) do set[item] = true end return set end --[[ Recursive deep copy function. Preserves identities of subtables. ]] local function _deepCopy(orig, includeMetatable, already_seen) -- Stores copies of tables indexed by the original table. already_seen = already_seen or {} local copy = already_seen[orig] if copy ~= nil then return copy end if type(orig) == 'table' then copy = {} for orig_key, orig_value in pairs(orig) do copy[deepcopy(orig_key, includeMetatable, already_seen)] = deepcopy(orig_value, includeMetatable, already_seen) end already_seen[orig] = copy if includeMetatable then local mt = getmetatable(orig) if mt ~= nil then local mt_copy = deepcopy(mt, includeMetatable, already_seen) setmetatable(copy, mt_copy) already_seen[mt] = mt_copy end end else -- number, string, boolean, etc copy = orig end return copy end function p.deepCopy(orig, noMetatable, already_seen) checkType("deepCopy", 3, already_seen, "table", true) return _deepCopy(orig, not noMetatable, already_seen) end --[[ Concatenates all values in the table that are indexed by a number, in order. sparseConcat{ a, nil, c, d } => "acd" sparseConcat{ nil, b, c, d } => "bcd" ]] function p.sparseConcat(t, sep, i, j) local list = {} local list_i = 0 for _, v in p.sparseIpairs(t) do list_i = list_i + 1 list[list_i] = v end return table.concat(list, sep, i, j) end --[[ -- This returns the length of a table, or the first integer key n counting from -- 1 such that t[n + 1] is nil. It is similar to the operator #, but may return -- a different value when there are gaps in the array portion of the table. -- Intended to be used on data loaded with mw.loadData. For other tables, use #. -- Note: #frame.args in frame object always be set to 0, regardless of -- the number of unnamed template parameters, so use this function for -- frame.args. --]] function p.length(t) local i = 1 while t[i] ~= nil do i = i + 1 end return i - 1 end function p.inArray(arr, valueToFind) checkType("inArray", 1, arr, "table") -- if valueToFind is nil, error? for _, v in ipairs(arr) do if v == valueToFind then return true end end return false end return p fe918509f168332267834b3a6f5c219a9de5b2e7 Модуль:Template call code 828 126 295 294 2024-08-10T15:20:57Z DuOfOrl 5 1 версия импортирована Scribunto text/plain local getArgs = require('Module:Arguments').getArgs local ru = mw.language.new('ru') local p = {} -- Используется для того, чтобы можно было удалять элементы из таблицы local function copy(other) local res = {} for k, v in pairs(other) do res[k] = v end return res end local function makeInvokeFunc(funcName, flags) return function (frame) local args = copy(getArgs(frame, { trim = false, removeBlanks = false })) return p[funcName](args, flags) end end --предотвращает обработку вики-текста в отображении образца local function processText(str, nowiki) local res = str if nowiki then str = mw.text.unstripNoWiki(str) str = string.gsub(str, '%[', '&#91;') str = string.gsub(str, '%]', '&#93;') str = string.gsub(str, '<', '&lt;') str = string.gsub(str, '>', '&gt;') str = string.gsub(str, '{', '&#123;') str = string.gsub(str, '|', '&#124;') str = string.gsub(str, '}', '&#125;') str = string.gsub(str, '\'', '&#39;') str = string.gsub(str, '"', '&quot;') str = string.gsub(str, '(://)', '<span>%1</span>') end return str end local function addParams(args, params) local text, equals_pos, param, value = '', 0, '', '' local function addPipe() if params.spaced then text = text .. ' ' end text = text .. '<span class="' if not params.spaced then text = text .. ' ts-templateCallCode-pipe' end if not params.black then text = text .. ' ts-templateCallCode-weak' end -- &#124;, чтобы не трактовалось как разделитель ячеек в таблицах text = text .. '">&#124;</span>' end local beforeParam = '<span class="ts-templateCallCode-param">' local afterParam = '</span>' for k, v in pairs(args) do if type(k) == 'number' then -- Неименованные параметры if k >= params.from then equals_pos = v:find('=') if equals_pos and v:find('{{=}}') == equals_pos - 2 then equals_pos = nil end if equals_pos then -- Содержащие «=» преобразуем в именованные param = v:sub(1, equals_pos - 1) value = v:sub(equals_pos + 1) addPipe() text = text .. beforeParam .. processText(param, params.nowiki) .. '=' .. processText(value, params.nowiki) .. afterParam else -- Истинно неименованные addPipe() local paramValue = processText(v, params.nowiki) if #paramValue ~= 0 then text = text .. beforeParam .. paramValue .. afterParam end end end elseif not k:find('^_') then -- Именованные параметры, исключая модификаторы внешнего вида addPipe() text = text .. beforeParam .. processText(k, params.nowiki) .. '=' .. processText(v, params.nowiki) .. afterParam end end return text end function p._main(args, flags) local name = args[1] table.remove(args, 1) -- Вещи типа «=» в первом параметре if not name then for k, v in pairs(args) do if not k:find('^_') then name = k .. '=' .. v args[k] = nil break end end end local optpText if not flags.withoutParams then if name then local spanOffset = mw.ustring.find(name, '<span') -- След использования шаблона optp if spanOffset then optpText = mw.ustring.sub(name, spanOffset) name = mw.ustring.sub(name, 1, spanOffset - 1) end end end local yesno = require('Module:Yesno') local nolink, subst, podst, global, nav, noRedirect, ucFirst, black, nobr local tag, style, comment, lang, sister, global, textInPlaceOfName, namePrefix, prefix, postfix, nowiki local spaced, from if flags.withoutParams then for i, v in ipairs(args) do if v == 'nl' or v == 'nolink' then noLink = true elseif v == 's' then subst = true elseif v == 'п' then podst = true elseif v == 'g' then global = true elseif v == 'nav' then nav = true elseif v == 'noredir' then noRedirect = true elseif v == 'u' then ucFirst = true elseif v == 'b' then black = true elseif v == 'nobr' then nobr = true end end tag = args.tag or 'span' style = args.style comment = args.comment lang = args.lang sister = args.sister textInPlaceOfName = args.text namePrefix = args.nameprefix prefix = args.prefix postfix = args.postfix nowiki = args.nowiki else noLink = yesno(args._nolink or args._nl, false) or not yesno(args._link, false) subst = yesno(args._s, false) podst = yesno(args['_п'], false) global = yesno(args._g, false) nav = yesno(args._nav, false) noRedirect = yesno(args._noredir, false) ucFirst = yesno(args._u, false) black = yesno(args._b, false) nobr = yesno(args._nobr, false) tag = args._tag or 'span' style = args._style comment = args._comment lang = args._lang sister = args._sister textInPlaceOfName = args._text namePrefix = args._nameprefix prefix = args._prefix postfix = args._postfix nowiki = args._nowiki spaced = yesno(args._spaced, false) from = (tonumber(args._from) or 2) - 1 end global = global or name and mw.ustring.sub(name, 1, 1) == ':' black = black or tag ~= 'span' if textInPlaceOfName == '' then textInPlaceOfName = nil end if comment == '' then comment = nil end if lang == '' then lang = nil end if sister == '' then sister = nil end if namePrefix == '' then namePrefix = nil end if name then local trimmedName = mw.text.trim(name) if ru:lc(mw.ustring.sub(trimmedName, 1, 6)) == 'subst:' then subst = true name = mw.ustring.sub(trimmedName, 7) end if ru:lc(mw.ustring.sub(trimmedName, 1, 6)) == 'подст:' then podst = true name = mw.ustring.sub(trimmedName, 7) end end if subst then namePrefix = 'subst:' elseif podst then namePrefix = 'подст:' end local currentTitle = mw.title.getCurrentTitle() -- При опущенном первом параметре берём имя шаблона из названия страницы if name == '' or not name then local currentTitleRoot = currentTitle.rootText if not ucFirst and ( ( ru:uc(currentTitleRoot) ~= currentTitleRoot and -- Книга:Литературное наследство, TranslateDate not mw.ustring.match(currentTitleRoot, '^[А-Яа-яA-Za-z]+:?[А-ЯA-Z]') ) or #currentTitleRoot == 1 ) then name = ru:lcfirst(currentTitleRoot) else name = currentTitleRoot end end -- Начинаем собирать код local linkBody, titleObject, linkBegin, linkDivider, linkEnd local prefixes = {} if lang then table.insert(prefixes, lang) end if sister then table.insert(prefixes, sister) end linkBody = table.concat(prefixes, ':') if #linkBody ~= 0 then linkBody = ':' .. linkBody end if mw.ustring.sub(name, 1, 1) ~= ':' then linkBody = linkBody .. ':' end if not global then linkBody = linkBody .. 'Template:' end linkBody = linkBody .. name titleObject = mw.title.new(linkBody) local noLink = noLink or currentTitle == titleObject if not noLink then if not noRedirect or ( noRedirect and not lang and not sister and not titleObject.exists ) then linkBegin = '[[' linkEnd = ']]' linkDivider = '|' else linkBegin = '[' linkEnd = ']' linkDivider = ' ' linkBody = titleObject:fullUrl('redirect=no') end end local text = '' if tag then text = text .. '<' .. tag .. ' class="ts-templateCallCode' if nobr then text = text .. ' nowrap' end text = text .. '"' if style then text = text .. ' style="' .. style .. '"' end text = text .. '>' end if prefix then text = text .. processText(prefix, nowiki) end text = text .. '<span class="' if not spaced then text = text .. ' ts-templateCallCode-opening' end if not black then text = text .. ' ts-templateCallCode-weak' end text = text .. '">{{' if namePrefix then text = text .. namePrefix end text = text .. '</span>' if nav and currentTitle == titleObject then text = text .. '\'\'\'' end text = text .. '<span class="ts-templateCallCode-templateName" data-navboxnavigation-link="0">' local commentedLabel if comment then -- https://phabricator.wikimedia.org/T200704 -- commentedLabel = mw.getCurrentFrame():expandTemplate({title = 'comment', args = {(textInPlaceOfName or name), comment}}) commentedLabel = '<span class="commentedText" title="' .. comment .. '" style="border-bottom: 1px dotted; cursor: help;">' .. (textInPlaceOfName or name) .. '</span>' end local label = (commentedLabel or textInPlaceOfName or name) if not noLink then if noRedirect then text = text .. '<span class="plainlinks">' end text = text .. linkBegin .. linkBody .. linkDivider .. label .. linkEnd if noRedirect then text = text .. '</span>' end else text = text .. label end text = text .. '</span>' if nav and currentTitle == titleObject then text = text .. '\'\'\'' end if not flags.withoutParams then if optpText then text = text .. optpText end text = text .. addParams(args, { spaced = spaced, black = black, nowiki = nowiki, from = from }) if spaced then text = text .. ' ' end end text = text .. '<span class="' if not spaced then text = text .. ' ts-templateCallCode-closing' end if not black then text = text .. ' ts-templateCallCode-weak' end text = text .. '">}}</span>' if postfix then text = text .. processText(postfix, nowiki) end if tag then text = text .. '</' .. tag .. '>' end local ts = mw.getCurrentFrame():extensionTag{ name = 'templatestyles', args = { src = 'Модуль:Template call code/styles.css' } } return ts .. text end function p._onlyParams(args) local yesno = require('Module:Yesno') return addParams(args, { spaced = yesno(args._spaced, false), black = true, nowiki = yesno(args._nowiki, false), from = 1 }) end p.withoutParams = makeInvokeFunc('_main', {withoutParams = true}) p.withParams = makeInvokeFunc('_main', {withoutParams = false}) p.onlyParams = makeInvokeFunc('_onlyParams') return p c4cde66869b509219e9bf629a766ce30ad0bdf97 Модуль:Yesno 828 127 297 296 2024-08-10T15:20:57Z DuOfOrl 5 1 версия импортирована Scribunto text/plain -- Function allowing for consistent treatment of boolean-like wikitext input. -- It works similarly to the template {{yesno}}. return function (val, default) -- If your wiki uses non-ascii characters for any of "yes", "no", etc., you -- should replace "val:lower()" with "mw.ustring.lower(val)" in the -- following line. val = type(val) == 'string' and val:lower() or val if val == nil then return nil elseif val == true or val == 'yes' or val == 'y' or val == 'true' or val == 't' or val == 'да' or val == 'д' -- кириллица or val == 'у' or val == '+' or tonumber(val) == 1 then return true elseif val == false or val == 'no' or val == 'n' or val == 'false' or val == 'f' or val == 'нет' or val == 'н' or val == '-' or tonumber(val) == 0 then return false else return default end end ae94e12a838e770797317ed07b57b330ffeb7658 Модуль:Template call code/styles.css 828 128 299 298 2024-08-10T15:20:58Z DuOfOrl 5 1 версия импортирована sanitized-css text/css .ts-templateCallCode-weak { color: #72777d; } .ts-templateCallCode-pipe { margin: 0 2px; } .ts-templateCallCode-pipe + .ts-templateCallCode-pipe, /* Template:Optp */ .ts-templateCallCode-pipe + .ts-templateCallCode-param > .ts-templateCallCode-weak:first-child > .ts-templateCallCode-pipe:first-child { margin-left: 0; } .ts-templateCallCode-param + .ts-templateCallCode-closing { margin-left: 2px; } span.ts-templateCallCode > .ts-templateCallCode-templateName a { /* Решение из https://ru.wikipedia.org/wiki/Шаблон:Фиттс */ padding: 0 0.5em !important; /* Перезаписываем стиль для .plainlinks a.external */ position: relative; margin: -0.5em; } /* [[Категория:Шаблоны:Подстраницы CSS]] */ b3ed166240cf28c48a58b8d992794b753b2c6ef5 Шаблон:Карточка 10 129 301 300 2024-08-10T15:20:58Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{#if:{{{имя|}}}|{{#ifeq:{{{имя|}}}|-||{{#if:{{{цвет|}}}|{{#tag:templatestyles| |wrapper=.infobox-{{#invoke:Hash|main|{{{имя}}} {{{вверху0|}}} {{{вверху|}}} {{{вверху2|}}}}} |src=Шаблон:Цвет/{{{цвет|}}}.css }}}}}}}}<table class="infobox infobox-{{#invoke:Hash|main|{{{имя}}} {{{вверху0|}}} {{{вверху|}}} {{{вверху2|}}}}} {{{класс_тела|}}}" style="{{{стиль_тела|}}}" {{#if:{{{имя|}}}|{{#ifeq:{{{имя|}}}|-||data-name="{{{имя}}}"}}}} {{#if:{{{from|}}}|{{#ifeq:{{{from|}}}|-||data-from="{{{from}}}"}}}}><!-- Вверху0 -->{{#if:{{{вверху0|}}}|<tr><td colspan="2" class="{{{класс_вверху0|}}}" style="text-align:center; {{{стиль_вверху0|}}}">{{{вверху0}}}</td></tr>}}<!-- Вверху -->{{#if:{{{вверху|}}}|<tr><th colspan="2" scope="colgroup" class="infobox-above {{{класс_вверху|}}}" style="{{{стиль_вверху|}}}">{{{вверху}}}</th></tr>}}<!-- Вверху2 -->{{#if:{{{вверху2|}}}|<tr><td colspan="2" class="{{{класс_вверху2|}}}" style="text-align:center; {{{стиль_вверху2|}}}">{{{вверху2}}}</td></tr>}}<!-- Вверху3 -->{{#if:{{{вверху3|}}}|<tr><td colspan="2" class="{{{класс_вверху3|}}}" style="text-align:center; {{{стиль_вверху3|}}}">{{{вверху3}}}</td></tr>}}<!-- Изображение -->{{#if:{{{изображение|}}}|<tr><td colspan="2" class="infobox-image {{{класс_изображения|}}}" style="{{{стиль_изображения|}}}"> {{{изображение}}} {{#if:{{{подпись|}}}| <div class="media-caption" style="{{{стиль_подписи|}}}">{{{подпись}}}</div>}}</td></tr>}}<!-- Изображение2 -->{{#if:{{{изображение2|}}}|<tr><td colspan="2" class="infobox-image {{{класс_изображения2|}}}" style="{{{стиль_изображения2|}}}"> {{{изображение2}}} {{#if:{{{подпись2|}}}| <div class="media-caption" style="{{{стиль_подписи2|}}}">{{{подпись2}}}</div>}}</td></tr>}}<!-- Изображение3 -->{{#if:{{{изображение3|}}}|<tr><td colspan="2" class="infobox-image {{{класс_изображения3|}}}" style="{{{стиль_изображения3|}}}"> {{{изображение3}}} {{#if:{{{подпись3|}}}| <div class="media-caption" style="{{{стиль_подписи3|}}}">{{{подпись3}}}</div>}}</td></tr>}}<!-- Строки -->{{#invoke:Infobox|renderLines}}<!-- Внизу -->{{Карточка/внизу| стиль_внизу_общий={{{стиль_внизу|}}}| класс_внизу={{{класс_внизу|}}}| внизу={{{внизу|}}}}}<!-- Внизу N -->{{#invoke:Transclude|npc|Карточка/внизу| стиль_внизу_общий={{{стиль_внизу|}}}| стиль_внизу=| класс_внизу=| внизу=}} </table><includeonly><!-- статьи -->{{#if:{{NAMESPACE}}||<!-- -->{{#if:{{{имя|}}}||[[Категория:Статьи с шаблонами-карточками без имени]]}}<!-- -->{{#ifeq:{{{имя|}}}|{{subst:PAGENAME}}|[[Категория:Статьи с шаблонами-карточками без имени]]}}<!-- -->}}<!-- шаблоны -->{{#ifeq:{{NAMESPACENUMBER}}|10|<!-- -->{{#if:{{{имя|}}}||[[Категория:Шаблоны-карточки без имени]]}}<!-- -->{{#ifeq:{{{имя|}}}|{{subst:PAGENAME}}|[[Категория:Шаблоны-карточки без имени]]}}<!-- -->{{#if:{{{название|}}}{{{стиль_названия|}}}|[[Категория:Шаблоны с использованием параметра «название» в шаблоне «Карточка»]]}}<!-- -->{{#if:{{{подпись|}}}{{{стиль_подписи|}}}{{{подпись2|}}}{{{стиль_подписи2|}}}{{{подпись3|}}}{{{стиль_подписи3|}}}|[[Категория:Шаблоны с использованием параметра «подпись» в шаблоне «Карточка»]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_тела|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_названия|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_вверху|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_вверху2|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_вверху3|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_подписи|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_подписи2|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_подписи3|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_заголовков|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_меток|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_текста|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_внизу|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifeq:{{{имя|}}}|{{PAGENAME}}|<!-- -->[[Категория:Шаблоны-карточки по алфавиту|{{ucfirst:{{без начала|{{PAGENAME}}|Карточка }}}}]]<!-- -->{{#if:{{{стиль_тела|}}}{{{стиль_вверху|}}}{{{стиль_заголовков|}}}{{{стиль_внизу|}}}|[[Категория:Википедия:Шаблоны-карточки с явным указанием стилей]]}}<!-- -->}}<!-- -->}}<!-- любое пространство имён -->{{#if:{{{название|}}}{{{стиль_названия|}}}|[[Категория:Википедия:Страницы с использованием параметра «название» в шаблоне «Карточка»]]}}<!-- -->{{#if:{{{подпись|}}}{{{стиль_подписи|}}}{{{подпись2|}}}{{{стиль_подписи2|}}}{{{подпись3|}}}{{{стиль_подписи3|}}}|[[Категория:Википедия:Страницы с использованием параметра «подпись» в шаблоне «Карточка»]]}}</includeonly><noinclude>{{doc}}</noinclude> 5bd0cadc0cad51dc109de7db63622ab36743d386 Шаблон:Карточка/название 10 130 303 302 2024-08-10T15:20:59Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{#if:{{{1|}}}|{{{1}}}|{{без уточнения|{{PAGENAME}}}}}}<noinclude> {{doc}} </noinclude> 110edc6d8286f120a048863c68371720bd4e65ca Шаблон:Yesno 10 131 305 304 2024-08-10T15:20:59Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{<includeonly>safesubst:</includeonly>#switch: {{<includeonly>safesubst:</includeonly>lc: {{{1|¬}}} }} |no |n |нет |false |0 = {{{no|<!-- null -->}}} | = {{{blank|{{{no|<!-- null -->}}}}}} |¬ = {{{¬|}}} |yes |y |да |true |1 = {{{yes|yes}}} |#default = {{{def|{{{yes|yes}}}}}} }}<noinclude> {{Documentation}} </noinclude> 4e236854c477d07a225c2ab6c016c389b133e8d3 Шаблон:Без уточнения 10 132 307 306 2024-08-10T15:20:59Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <includeonly>{{ {{{|safesubst:}}}#invoke:String|replace|{{{1|{{ {{{|safesubst:}}}PAGENAME}}}}}|^%s*(.+)%s+%b()%s*$|%1||false}}</includeonly><noinclude>{{doc}}</noinclude> 1fcb3edb0be49656ae0f913e9a8fb4853264b480 Шаблон:Wikidata number switch 10 134 311 310 2024-08-10T15:21:00Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{#if: {{{3|}}} | {{#if: {{{5|}}} | {{{5|}}} | {{{3|}}} }} | {{#if: {{{2|}}} | {{#if: {{{4|}}} | {{{4|}}} | {{{2|}}} }} | {{#if: {{{1|}}} | {{#if: {{{4|}}}{{{5|}}} | {{#if: {{wikidata|{{{1|}}}|property-module=Wikidata/count|property-function=isMultiple|from={{{from|}}}}} | {{{5|}}} | {{{4|}}} }} | {{wikidata|{{{1|}}}|from={{{from|}}}}} }} }} }} }}<noinclude> {{doc}} </noinclude> 7541bb47e73905a8ee240baa1dab1801f9f7b166 Шаблон:Карточка/Викисклад 10 135 313 312 2024-08-10T15:21:00Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{wikidata|p373|{{str rep|{{str rep|{{{1|}}}|Category:|}}|category:|}}|plain=false|text=Медиафайлы на Викискладе|icon={{{icon|}}}|icon_size={{{icon_size|}}}|from={{{from|}}}}}<!-- -->{{#if: {{{nocat|}}}{{NAMESPACE}} || <!-- -->{{#if: {{{1|}}} | [[Категория:Википедия:Ссылка на Викисклад непосредственно в статье]]<!-- -->{{#if: {{wikidata|p373|plain=true}} | {{#ifeq: {{str rep|{{str rep|{{{1|}}}|Category:|}}|category:|}} | {{wikidata|p373|plain=true}} |[[Категория:Википедия:Ссылки на Викисклад в статье и на Викиданных совпадают]]| [[Категория:Википедия:Ссылки на Викисклад в статье и на Викиданных отличаются]] }} | [[Категория:Википедия:Ссылка на Викисклад в статье, но не на Викиданных]] }} }}<!-- --> }}<!-- -->{{#ifeq: {{NAMESPACE}} | Шаблон | {{#if: {{{2|}}} | [[Категория:Википедия:Шаблоны для низа карточек с лишним параметром]] }} }}<!-- --><noinclude> {{doc}} </noinclude> 40ef9a463c772ddbf54feae9e21d4037b692253e Шаблон:Str rep 10 136 315 314 2024-08-10T15:21:01Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <includeonly>{{{{{|safesubst:}}}#invoke:String|replace|source={{{1}}}|{{{2}}}|{{{3}}}|{{{4|1}}}}}</includeonly><noinclude>{{doc}}</noinclude> c75032f150c372324c69a6f62ff4ab1492ad4cfa Шаблон:Карточка/внизу 10 137 317 316 2024-08-10T15:21:01Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <includeonly>{{#if:{{{внизу|}}}|<tr><td colspan="2" class="infobox-below {{{класс_внизу|}}}" style="{{{стиль_внизу_общий|}}};{{{стиль_внизу|}}}">{{{внизу|}}}</td></tr>}}</includeonly><noinclude> {{doc}} </noinclude> 169fb2d10b0847c2fd677eda9f159ba99025198f Модуль:String 828 138 319 318 2024-08-10T15:21:01Z DuOfOrl 5 1 версия импортирована Scribunto text/plain --[[ This module is intended to provide access to basic string functions. Most of the functions provided here can be invoked with named parameters, unnamed parameters, or a mixture. If named parameters are used, Mediawiki will automatically remove any leading or trailing whitespace from the parameter. Depending on the intended use, it may be advantageous to either preserve or remove such whitespace. Global options ignore_errors: If set to 'true' or 1, any error condition will result in an empty string being returned rather than an error message. error_category: If an error occurs, specifies the name of a category to include with the error message. The default category is [Category:Errors reported by Module String]. no_category: If set to 'true' or 1, no category will be added if an error is generated. Unit tests for this module are available at Module:String/tests. ]] local str = {} --[[ subcount This function returns the count of substring in source string. Usage: {{#invoke:String|subcount|source_string|substring|plain_flag}} OR {{#invoke:String|subcount|s=source_string|pattern=substring|plain=plain_flag}} Parameters s: The string to search pattern: The pattern or string to find within the string plain: A flag indicating that the substring should be understood as plain text. Defaults to true. If invoked using named parameters, Mediawiki will automatically remove any leading or trailing whitespace from the target string. ]] function str.subcount( frame ) local new_args = str._getParameters( frame.args, {'s', 'pattern', 'plain'} ); local s = new_args['s'] or ''; local plain_flag = str._getBoolean( new_args['plain'] or true ); local pattern = new_args['pattern'] or ''; if s == '' or pattern == '' then return 0; end if plain_flag then pattern = str._escapePattern( pattern ); end local _, count = mw.ustring.gsub(s, pattern, "") return count; end --[[ len This function returns the length of the target string. Usage: {{#invoke:String|len|target_string|}} OR {{#invoke:String|len|s=target_string}} Parameters s: The string whose length to report If invoked using named parameters, Mediawiki will automatically remove any leading or trailing whitespace from the target string. ]] function str.len( frame ) local new_args = str._getParameters( frame.args, {'s'} ); local s = new_args['s'] or ''; return mw.ustring.len( s ) end --[[ sub This function returns a substring of the target string at specified indices. Usage: {{#invoke:String|sub|target_string|start_index|end_index}} OR {{#invoke:String|sub|s=target_string|i=start_index|j=end_index}} Parameters s: The string to return a subset of i: The fist index of the substring to return, defaults to 1. j: The last index of the string to return, defaults to the last character. The first character of the string is assigned an index of 1. If either i or j is a negative value, it is interpreted the same as selecting a character by counting from the end of the string. Hence, a value of -1 is the same as selecting the last character of the string. If the requested indices are out of range for the given string, an error is reported. ]] function str.sub( frame ) local new_args = str._getParameters( frame.args, { 's', 'i', 'j' } ); local s = new_args['s'] or ''; local i = tonumber( new_args['i'] ) or 1; local j = tonumber( new_args['j'] ) or -1; local len = mw.ustring.len( s ); -- Convert negatives for range checking if i < 0 then i = len + i + 1; end if j < 0 then j = len + j + 1; end if i > len or j > len or i < 1 or j < 1 then return str._error( 'Значение индекса подстроки выходит за допустимые границы' ); end if j < i then return str._error( 'Неверный порядок индексов подстроки' ); end return mw.ustring.sub( s, i, j ) end --[[ This function implements that features of {{str sub old}} and is kept in order to maintain these older templates. ]] function str.sublength( frame ) local i = tonumber( frame.args.i ) or 0 local len = tonumber( frame.args.len ) return mw.ustring.sub( frame.args.s, i + 1, len and ( i + len ) ) end --[[ match This function returns a substring from the source string that matches a specified pattern. Usage: {{#invoke:String|match|source_string|pattern_string|start_index|match_number|plain_flag|nomatch_output}} OR {{#invoke:String|pos|s=source_string|pattern=pattern_string|start=start_index |match=match_number|plain=plain_flag|nomatch=nomatch_output}} Parameters s: The string to search pattern: The pattern or string to find within the string start: The index within the source string to start the search. The first character of the string has index 1. Defaults to 1. match: In some cases it may be possible to make multiple matches on a single string. This specifies which match to return, where the first match is match= 1. If a negative number is specified then a match is returned counting from the last match. Hence match = -1 is the same as requesting the last match. Defaults to 1. plain: A flag indicating that the pattern should be understood as plain text. Defaults to false. nomatch: If no match is found, output the "nomatch" value rather than an error. If invoked using named parameters, Mediawiki will automatically remove any leading or trailing whitespace from each string. In some circumstances this is desirable, in other cases one may want to preserve the whitespace. If the match_number or start_index are out of range for the string being queried, then this function generates an error. An error is also generated if no match is found. If one adds the parameter ignore_errors=true, then the error will be suppressed and an empty string will be returned on any failure. For information on constructing Lua patterns, a form of [regular expression], see: * http://www.lua.org/manual/5.1/manual.html#5.4.1 * http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Patterns * http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Ustring_patterns ]] function str.match( frame ) local new_args = str._getParameters( frame.args, {'s', 'pattern', 'start', 'match', 'plain', 'nomatch'} ); local s = new_args['s'] or ''; local start = tonumber( new_args['start'] ) or 1; local plain_flag = str._getBoolean( new_args['plain'] or false ); local pattern = new_args['pattern'] or ''; local match_index = math.floor( tonumber(new_args['match']) or 1 ); local nomatch = new_args['nomatch']; if s == '' then return str._error( 'Пустая строка поиска' ); end if pattern == '' then return str._error( 'Пустой шаблон поиска' ); end if math.abs(start) < 1 or math.abs(start) > mw.ustring.len( s ) then return str._error( 'Индекс начала поиска выходит за допустимые границы' ); end if match_index == 0 then return str._error( 'Индекс совпадения выходит за допустимые границы' ); end if plain_flag then pattern = str._escapePattern( pattern ); end local result if match_index == 1 then -- Find first match is simple case result = mw.ustring.match( s, pattern, start ) else if start > 1 then s = mw.ustring.sub( s, start ); end local iterator = mw.ustring.gmatch(s, pattern); if match_index > 0 then -- Forward search for w in iterator do match_index = match_index - 1; if match_index == 0 then result = w; break; end end else -- Reverse search local result_table = {}; local count = 1; for w in iterator do result_table[count] = w; count = count + 1; end result = result_table[ count + match_index ]; end end if result == nil then if nomatch == nil then return str._error( 'Совпадение не найдено' ); else return nomatch; end else return result; end end --[[ pos This function returns a single character from the target string at position pos. Usage: {{#invoke:String|pos|target_string|index_value}} OR {{#invoke:String|pos|target=target_string|pos=index_value}} Parameters target: The string to search pos: The index for the character to return If invoked using named parameters, Mediawiki will automatically remove any leading or trailing whitespace from the target string. In some circumstances this is desirable, in other cases one may want to preserve the whitespace. The first character has an index value of 1. If one requests a negative value, this function will select a character by counting backwards from the end of the string. In other words pos = -1 is the same as asking for the last character. A requested value of zero, or a value greater than the length of the string returns an error. ]] function str.pos( frame ) local new_args = str._getParameters( frame.args, {'target', 'pos'} ); local target_str = new_args['target'] or ''; local pos = tonumber( new_args['pos'] ) or 0; if pos == 0 or math.abs(pos) > mw.ustring.len( target_str ) then return str._error( 'Значение индекса строки выходит за допустимые границы' ); end return mw.ustring.sub( target_str, pos, pos ); end --[[ str_find This function duplicates the behavior of {{str_find}}, including all of its quirks. This is provided in order to support existing templates, but is NOT RECOMMENDED for new code and templates. New code is recommended to use the "find" function instead. Returns the first index in "source" that is a match to "target". Indexing is 1-based, and the function returns -1 if the "target" string is not present in "source". Important Note: If the "target" string is empty / missing, this function returns a value of "1", which is generally unexpected behavior, and must be accounted for separatetly. ]] function str.str_find( frame ) local new_args = str._getParameters( frame.args, {'source', 'target'} ); local source_str = new_args['source'] or ''; local target_str = new_args['target'] or ''; if target_str == '' then return 1; end local start = mw.ustring.find( source_str, target_str, 1, true ) if start == nil then start = -1 end return start end --[[ find This function allows one to search for a target string or pattern within another string. Usage: {{#invoke:String|find|source_str|target_string|start_index|plain_flag}} OR {{#invoke:String|find|source=source_str|target=target_str|start=start_index|plain=plain_flag}} Parameters source: The string to search target: The string or pattern to find within source start: The index within the source string to start the search, defaults to 1 plain: Boolean flag indicating that target should be understood as plain text and not as a Lua style regular expression, defaults to true If invoked using named parameters, Mediawiki will automatically remove any leading or trailing whitespace from the parameter. In some circumstances this is desirable, in other cases one may want to preserve the whitespace. This function returns the first index >= "start" where "target" can be found within "source". Indices are 1-based. If "target" is not found, then this function returns 0. If either "source" or "target" are missing / empty, this function also returns 0. This function should be safe for UTF-8 strings. ]] function str.find( frame ) local new_args = str._getParameters( frame.args, {'source', 'target', 'start', 'plain' } ); local source_str = new_args['source'] or ''; local pattern = new_args['target'] or ''; local start_pos = tonumber(new_args['start']) or 1; local plain = new_args['plain'] or true; if source_str == '' or pattern == '' then return 0; end plain = str._getBoolean( plain ); local start = mw.ustring.find( source_str, pattern, start_pos, plain ) if start == nil then start = 0 end return start end --[[ replace This function allows one to replace a target string or pattern within another string. Usage: {{#invoke:String|replace|source_str|pattern_string|replace_string|replacement_count|plain_flag}} OR {{#invoke:String|replace|source=source_string|pattern=pattern_string|replace=replace_string| count=replacement_count|plain=plain_flag}} Parameters source: The string to search pattern: The string or pattern to find within source replace: The replacement text count: The number of occurences to replace, defaults to all. plain: Boolean flag indicating that pattern should be understood as plain text and not as a Lua style regular expression, defaults to true ]] function str.replace( frame ) local new_args = str._getParameters( frame.args, {'source', 'pattern', 'replace', 'count', 'plain' } ); local source_str = new_args['source'] or ''; local pattern = new_args['pattern'] or ''; local replace = new_args['replace'] or ''; local count = tonumber( new_args['count'] ); local plain = new_args['plain'] or true; if source_str == '' or pattern == '' then return source_str; end plain = str._getBoolean( plain ); if plain then pattern = str._escapePattern( pattern ); replace = mw.ustring.gsub( replace, "%%", "%%%%" ); --Only need to escape replacement sequences. end local result; if count ~= nil then result = mw.ustring.gsub( source_str, pattern, replace, count ); else result = mw.ustring.gsub( source_str, pattern, replace ); end return result; end --[[ This function adds support for escaping parts of the patterns when using [plain=false]. ]] function str.escape( frame ) local new_args = str._getParameters( frame.args, {'pattern' } ); local pattern = new_args['pattern'] or ''; local result = ''; result = str._escapePattern( pattern ); return result; end --[[ Internal compare string function ]] function str._strcmp(a , b) local s1c = mw.ustring.gcodepoint( a ); local s2c = mw.ustring.gcodepoint( b ); while true do local c1 = s1c(); local c2 = s2c(); if c1 == nil then if c2 == nil then return 0 else return -1 end else if c2 ~= nil then if c1 ~= c2 then return c1 < c2 and -1 or 1 end else return 1 end end end return 0 end --[[ compare This function compare two UTF-8 strings Usage: {{#invoke:String|compare|str1|str2}} Returns: 0 - if strings are equal 1 - if st1 > str2 -1 - if str1 < str2 ]] function str.compare(frame) local str1 = frame.args[1] or ''; local str2 = frame.args[2] or ''; return str._strcmp(str1 , str2) end --[[ simple function to pipe string.rep to templates. ]] function str.rep( frame ) local repetitions = tonumber( frame.args[2] ) if not repetitions then return str._error( 'функция rep ожидает число во втором параметре, а получено "' .. ( frame.args[2] or '' ) .. '"' ) end return string.rep( frame.args[1] or '', repetitions ) end --[[ Helper function that populates the argument list given that user may need to use a mix of named and unnamed parameters. This is relevant because named parameters are not identical to unnamed parameters due to string trimming, and when dealing with strings we sometimes want to either preserve or remove that whitespace depending on the application. ]] function str._getParameters( frame_args, arg_list ) local new_args = {}; local index = 1; local value; for i,arg in ipairs( arg_list ) do value = frame_args[arg] if value == nil then value = frame_args[index]; index = index + 1; end new_args[arg] = value; end return new_args; end --[[ Helper function to handle error messages. ]] function str._error( error_str ) local frame = mw.getCurrentFrame(); local error_category = frame.args.error_category or 'Страницы с ошибками модуля String'; local ignore_errors = frame.args.ignore_errors or false; local no_category = frame.args.no_category or false; if str._getBoolean(ignore_errors) then return ''; end local error_str = '<strong class="error">Ошибка модуля String: ' .. error_str .. '</strong>'; if error_category ~= '' and not str._getBoolean( no_category ) then error_str = '[[Категория:' .. error_category .. ']]' .. error_str; end return error_str; end --[[ Helper Function to interpret boolean strings ]] function str._getBoolean( boolean_str ) local boolean_value; if type( boolean_str ) == 'string' then boolean_str = boolean_str:lower(); if boolean_str == 'false' or boolean_str == 'no' or boolean_str == '0' or boolean_str == '' then boolean_value = false; else boolean_value = true; end elseif type( boolean_str ) == 'boolean' then boolean_value = boolean_str; else error( 'Логическое значение не найдено' ); end return boolean_value end --[[ Helper function that escapes all pattern characters so that they will be treated as plain text. ]] function str._escapePattern( pattern_str ) return mw.ustring.gsub( pattern_str, "([%(%)%.%%%+%-%*%?%[%^%$%]])", "%%%1" ); end return str b4a4e099d7fab23576bae7af327a44c87d13f9cb Модуль:Sources 828 140 323 322 2024-08-10T15:21:02Z DuOfOrl 5 1 версия импортирована Scribunto text/plain ---@alias args table ---@alias frame { args: args, extensionTag: function, newChild: ( fun( args: args ): frame ) } ---@alias source { publication: source, [string]: any } ---@alias value: string | { id: string } ---@alias snak { datatype: string, snaktype: string, datavalue: { type: string, value: value } } ---@alias snaks table<string, table<number, snak>> ---@alias statement { mainsnak: snak, rank: string, qualifiers: snaks } ---@alias statements table<string, table<number, statement>> ---@alias map { name: string, ids: string[] }[]> ---@type table local p = {} ---@type table<string, string> local NORMATIVE_DOCUMENTS = { Q20754888 = 'Закон Российской Федерации', Q20754884 = 'Закон РСФСР', Q20873831 = 'Распоряжение Президента Российской Федерации', Q20873834 = 'Указ исполняющего обязанности Президента Российской Федерации', Q2061228 = 'Указ Президента Российской Федерации', } ---@type table<string, string> local LANG_CACHE = { Q150 = 'fr', Q188 = 'de', Q1321 = 'es', Q1860 = 'en', Q652 = 'it', Q7737 = 'ru', Q8798 = 'uk', } ---@type map local PROPERTY_MAP = { { name = 'sourceId', ids = { 'P248', 'P805' } }, { name = 'lang', ids = { 'P407', 'P364' } }, { name = 'author', ids = { 'P50', 'P2093' } }, { name = 'part', ids = { 'P958', 'P1810' } }, { name = 'title', ids = { 'P1476' } }, { name = 'subtitle', ids = { 'P1680' } }, { name = 'url', ids = { 'P953', 'P1065', 'P854', 'P973', 'P2699', 'P888' } }, { name = 'editor', ids = { 'P98' } }, { name = 'translator', ids = { 'P655' } }, { name = 'publication-id', ids = { 'P1433' } }, { name = 'edition', ids = { 'P393' } }, { name = 'publisher', ids = { 'P123' } }, { name = 'place', ids = { 'P291' } }, { name = 'volume', ids = { 'P478' } }, { name = 'issue', ids = { 'P433' } }, { name = 'dateOfCreation', ids = { 'P571' } }, { name = 'dateOfPublication', ids = { 'P577' } }, { name = 'pages', ids = { 'P304' } }, { name = 'numberOfPages', ids = { 'P1104' } }, { name = 'tirage', ids = { 'P1092' } }, { name = 'isbn', ids = { 'P212', 'P957' } }, { name = 'issn', ids = { 'P236' } }, -- { name = 'accessdate', ids = { 'P813' } }, -- disable, creates duplicate references { name = 'docNumber', ids = { 'P1545' } }, { name = 'type', ids = { 'P31' } }, { name = 'arxiv', ids = { 'P818' } }, { name = 'doi', ids = { 'P356' } }, { name = 'pmid', ids = { 'P698' } }, } -- table.insert( PROPERTY_MAP.url, 'P856' ) -- only as qualifier ---@type map local PUBLICATION_PROPERTY_MAP = mw.clone( PROPERTY_MAP ) ---@type string[] local monthGen = { 'января', 'февраля', 'марта', 'апреля', 'мая', 'июня', 'июля', 'августа', 'сентября', 'октября', 'ноября', 'декабря' } ---@type string local i18nDefaultLanguage = mw.language.getContentLanguage():getCode() p.i18nDefaultLanguage = i18nDefaultLanguage ---@type string local i18nEtAlDefault = ' et al.' ---@type table<string, string> local i18nEtAl = { ru = ' и др.', uk = ' та ін.', } ---@type table<string, string> local i18nEditors = { fr = '', de = 'Hrsg.: ', es = '', en = '', it = '', ru = 'под ред. ', uk = 'за ред. ', } ---@type table<string, string> local i18nTranslators = { fr = '', de = '', es = '', en = '', it = '', ru = 'пер. ', uk = 'пер. ', } ---@type table<string, string> local i18nVolume = { de = 'Vol.', fr = 'Vol.', es = 'Vol.', en = 'Vol.', it = 'Vol.', ru = 'Т.', uk = 'Т.', } ---@type table<string, string> local i18nIssue = { en = 'Iss.', ru = 'вып.', uk = 'вип.', } ---@type table<string, string> local i18nPages = { fr = 'P.', de = 'S.', es = 'P.', en = 'P.', it = 'P.', ru = 'С.', uk = 'С.', } ---@type table<string, string> local i18nNumberOfPages = { en = 'p.', ru = 'с.', } ---@type table<string, string> local i18nTirage = { en = 'ed. size: %d', ru = '%d экз.', } ---@param args args ---@return source local function getFilledArgs( args ) ---@type source local data = {} for key, value in pairs( args ) do if mw.text.trim( value ) ~= '' then if key == 1 then key = 'sourceId' end data[ key ] = mw.text.trim( value ) end end return data end ---Returns formatted pair {Family name(s), First name(s)} ---@param fullName string ---@return table<number, string> local function tokenizeName( fullName ) local space = '%s+' -- matches single or more spacing character local name = "(%a[%a%-']*)%.?" -- matches single name, have to start with letter, can contain apostrophe and hyphen, may end with dot local surname = "(%a[%a%-']*)" -- same as name, but can't end with dot local surnamePrefixes = { 'ван', 'van', 'де', 'de' } local nm, nm2, srn, srn2, pref fullName = ' ' .. fullName .. ' ' fullName = mw.ustring.gsub( fullName, ' оглы ', ' ' ) fullName = mw.text.trim( fullName ) -- Surname, Name local pattern = '^' .. surname .. ',' .. space .. name .. '$' srn, nm = mw.ustring.match( fullName, pattern ) if srn then return { srn, mw.ustring.sub( nm, 1, 1 ) .. '.' } end -- Surname, Name prefix for _, surnamePrefix in pairs( surnamePrefixes ) do pattern = '^' .. surname .. ',' .. space .. name .. space .. '(' .. surnamePrefix .. ')' .. '$' srn, nm, pref = mw.ustring.match( fullName, pattern ) if srn then return { mw.ustring.sub( pref ) .. ' ' .. srn, mw.ustring.sub( nm, 1, 1 ) .. '.' } end end -- Surname, Name Name pattern = '^' .. surname .. ',' .. space .. name .. space .. name .. '$' srn, nm, nm2 = mw.ustring.match( fullName, pattern ) if srn then return { srn, mw.ustring.sub( nm, 1, 1 ) .. '.&nbsp;' .. mw.ustring.sub( nm2, 1, 1 ) .. '.' } end -- Surname Surname, Name pattern = '^' .. surname .. space .. surname .. ',' .. space .. name .. '$' srn, srn2, nm = mw.ustring.match( fullName, pattern ) if srn then return { srn .. '&nbsp;' .. srn2, mw.ustring.sub( nm, 1, 1 ) .. '.' } end -- Name Name Surname pattern = '^' .. name .. space .. name .. space .. surname .. '$' nm, nm2, srn = mw.ustring.match( fullName, pattern ) if srn then return { srn, mw.ustring.sub( nm, 1, 1 ) .. '.&nbsp;' .. mw.ustring.sub( nm2, 1, 1 ) .. '.' } end -- Name Name prefix Surname for _, surnamePrefix in pairs( surnamePrefixes ) do pattern = '^' .. name .. space .. name .. space .. '(' .. surnamePrefix .. ')' .. space .. surname .. '$' nm, nm2, pref, srn = mw.ustring.match( fullName, pattern ) if srn then return { mw.ustring.sub( pref ) .. ' ' .. srn, mw.ustring.sub( nm, 1, 1 ) .. '.&nbsp;' .. mw.ustring.sub( nm2, 1, 1 ) .. '.' } end end -- Surname, Name Name prefix for _, surnamePrefix in pairs( surnamePrefixes ) do pattern = '^' .. surname .. ',' .. space .. name .. space .. name .. space .. '(' .. surnamePrefix .. ')' .. '$' srn, nm, nm2, pref = mw.ustring.match( fullName, pattern ) if srn then return { mw.ustring.sub( pref ) .. ' ' .. srn, mw.ustring.sub( nm, 1, 1 ) .. '.&nbsp;' .. mw.ustring.sub( nm2, 1, 1 ) .. '.' } end end -- Name{1,4} Surname for k = 1, 4 do pattern = '^' .. string.rep( name .. space, k ) .. surname .. '$' ---@type string[] local matched = { mw.ustring.match( fullName, pattern ) } if #matched ~= 0 then for j = 1, k do matched[ j ] = mw.ustring.sub( matched[ j ], 1, 1 ) end return { matched[ k + 1 ], table.concat( matched, '.&nbsp;', 1, k ) .. '.' } end end -- Surname Name{1,4} for k = 1, 4 do pattern = '^' .. surname .. string.rep( space .. name, k ) .. '$' ---@type string[] local matched = { mw.ustring.match( fullName, pattern ) } if #matched ~= 0 then for j = 2, k + 1 do matched[ j ] = mw.ustring.sub( matched[ j ], 1, 1 ) end return { matched[ 1 ], table.concat( matched, '.&nbsp;', 2, k + 1 ) .. '.' } end end return { fullName } end ---@param fullName string | nil ---@return string | nil local function personNameToAuthorName( fullName ) if not fullName then return nil end local tokenized = tokenizeName( fullName ) if #tokenized == 1 then return tokenized[ 1 ] end return tokenized[ 1 ] .. '&nbsp;' .. tokenized[ 2 ] end ---@param fullName string | nil ---@return string | nil local function personNameToResponsibleName( fullName ) if not fullName then return nil end local tokenized = tokenizeName( fullName ) if #tokenized == 1 then return tokenized[ 1 ] end return tokenized[ 2 ] .. '&nbsp;' .. tokenized[ 1 ] end ---@alias options { separator: string, conjunction: string, format: ( fun( data: string ): string ), nolinks: boolean, preferids: boolean, short: boolean } ---@type options local options_commas = { separator = ', ', conjunction = ', ', format = function( data ) return data end, nolinks = false, preferids = false, short = false, } ---@type options local options_commas_short = mw.clone( options_commas ) options_commas_short.short = true ---@type options local options_commas_it_short = mw.clone( options_commas_short ) options_commas_it_short.format = function( data ) return "''" .. data .. "''" end ---@type options local options_commas_nolinks = mw.clone( options_commas ) options_commas_nolinks.nolinks = true ---@type options local options_citetypes = { separator = ' ', conjunction = ' ', format = function( data ) return 'citetype_' .. data end, nolinks = true , preferids = true, short = false, } ---@type options local options_commas_authors = mw.clone( options_commas ) options_commas_authors.format = personNameToAuthorName ---@type options local options_commas_responsible = mw.clone( options_commas ) options_commas_responsible.format = personNameToResponsibleName ---@type options local options_ids = { separator = '; ', conjunction = '; ', format = function( id ) return id end, nolinks = true, preferids = false, short = false, } ---@type options local options_arxiv = mw.clone( options_ids ) options_arxiv.format = function( id ) return '[https://arxiv.org/abs/' .. id .. ' arXiv:' .. id .. ']' end ---@type options local options_doi = mw.clone( options_ids ) options_doi.format = function( doi ) return '[https://dx.doi.org/' .. doi .. ' doi:' .. doi .. ']' end ---@type options local options_issn = mw.clone( options_ids ) options_issn.format = function( issn ) return '[https://www.worldcat.org/issn/' .. issn .. ' ' .. issn .. ']' end ---@type options local options_pmid = mw.clone( options_ids ) options_pmid.format = function( pmid ) return '[https://www.ncbi.nlm.nih.gov/pubmed/?term=' .. pmid .. ' PMID:' .. pmid .. ']' end ---@param str string | nil ---@return boolean local function isEmpty( str ) return not str or #str == 0 end ---@param allQualifiers snaks ---@param qualifierPropertyId string ---@return string | nil local function getSingleStringQualifierValue( allQualifiers, qualifierPropertyId ) if not allQualifiers or not allQualifiers[ qualifierPropertyId ] then return nil end ---@type table<number, snak> local propertyQualifiers = allQualifiers[ qualifierPropertyId ] for _, qualifier in pairs( propertyQualifiers ) do if ( qualifier and qualifier.datatype == 'string' and qualifier.datavalue and qualifier.datavalue.type == 'string' and qualifier.datavalue.value ~= '' ) then return qualifier.datavalue.value end end return nil end ---@param data table ---@param resultProperty string ---@return void local function appendImpl_toTable( data, resultProperty ) if not data[ resultProperty ] then data[ resultProperty ] = {} elseif ( type( data[ resultProperty ] ) == 'string' or ( type( data[ resultProperty ] ) == 'table' and type( data[ resultProperty ].id ) == 'string' ) ) then data[ resultProperty ] = { data[ resultProperty ] } end end ---@param datavalue table ---@param qualifiers snaks ---@param data table ---@param propertyName string ---@param options table local function appendImpl( datavalue, qualifiers, data, propertyName, options ) data[ propertyName ] = data[ propertyName ] or {} if propertyName == 'issn' then table.insert( data[ propertyName ], datavalue.value ) elseif propertyName == 'url' or datavalue.type == 'url' then local value = datavalue.value if options.format then value = options.format( value ) end appendImpl_toTable( data, propertyName ) table.insert( data[ propertyName ], value ) elseif datavalue.type == 'string' then local value = getSingleStringQualifierValue( qualifiers, 'P1932' ) if not value then value = getSingleStringQualifierValue( qualifiers, 'P1810' ) end if not value then value = datavalue.value if options.format then value = options.format( value ) end end appendImpl_toTable(data, propertyName) local pos = getSingleStringQualifierValue( qualifiers, 'P1545' ) if pos then table.insert( data[ propertyName ], tonumber(pos), value ) else table.insert( data[ propertyName ], value ) end elseif datavalue.type == 'monolingualtext' then local value = datavalue.value.text if options.format then value = options.format( value ) end appendImpl_toTable( data, propertyName ) table.insert( data[ propertyName ], value ) elseif datavalue.type == 'quantity' then local value = datavalue.value.amount if ( mw.ustring.sub( value , 1, 1 ) == '+' ) then value = mw.ustring.sub( value , 2 ) end if options.format then value = options.format( value ) end appendImpl_toTable( data, propertyName ) table.insert( data[ propertyName ], value ) elseif datavalue.type == 'wikibase-entityid' then local pos = getSingleStringQualifierValue( qualifiers, 'P1545' ) local value = datavalue.value appendImpl_toTable(data, propertyName) local label = getSingleStringQualifierValue( qualifiers, 'P1932' ) if not label then label = getSingleStringQualifierValue( qualifiers, 'P1810' ) end local toInsert = { id = value.id, label = label } if pos and tonumber( pos ) then table.insert( data[ propertyName ], tonumber( pos ), toInsert ) else table.insert( data[ propertyName ], toInsert ) end elseif datavalue.type == 'time' then local value = datavalue.value if options.format then value = options.format( value ) end appendImpl_toTable( data, propertyName ) table.insert( data[ propertyName ], tostring( value.time ) ) end end ---@param entityId string ---@param propertyId string ---@return table<number, statement> local function getAllStatements( entityId, propertyId ) ---@type boolean, table<number, statement> local wdStatus, statements = pcall( mw.wikibase.getAllStatements, entityId, propertyId ) if wdStatus and statements then return statements end return {} end ---@param entityId string ---@param propertyId string ---@return table<number, statement> local function getBestStatements( entityId, propertyId ) ---@type boolean, table<number, statement> local wdStatus, statements = pcall( mw.wikibase.getBestStatements, entityId, propertyId ) if wdStatus and statements then return statements end return {} end ---@param entityId string ---@param projectToCheck string? ---@return string | nil local function getSitelink( entityId, projectToCheck ) ---@type boolean, string local wbStatus, sitelink if projectToCheck then wbStatus, sitelink = pcall( mw.wikibase.getSitelink, entityId, projectToCheck ) else wbStatus, sitelink = pcall( mw.wikibase.getSitelink, entityId ) end if not wbStatus then return nil end return sitelink end ---@param args any[] ---@return any | nil local function coalesce( args ) for _, arg in pairs( args ) do if not isEmpty( arg ) then return arg end end return nil end ---@param value any ---@return string | nil local function getSingle( value ) if type( value ) == 'string' then return tostring( value ) elseif type( value ) == 'table' then if value.id then return tostring( value.id ) end for _, tableValue in pairs( value ) do return getSingle( tableValue ) end end return nil end ---@param langEntityId string ---@return string | nil local function getLangCode( langEntityId ) if not langEntityId then return nil end langEntityId = getSingle( langEntityId ) if not string.match( langEntityId, '^Q%d+$' ) then return langEntityId end local cached = LANG_CACHE[ langEntityId ] if cached then if cached == '' then return nil end return cached end local claims = getBestStatements( langEntityId, 'P424' ) for _, claim in pairs( claims ) do if claim and claim.mainsnak and claim.mainsnak.datavalue and claim.mainsnak.datavalue.value then LANG_CACHE[ langEntityId ] = claim.mainsnak.datavalue.value return claim.mainsnak.datavalue.value end end LANG_CACHE[ langEntityId ] = '' return nil end ---@param entityId string ---@param propertyId string ---@param data source ---@param propertyName string ---@param options table? ---@return void local function appendEntitySnaks( entityId, propertyId, data, propertyName, options ) options = options or {} -- do not populate twice if data[ propertyName ] and ( propertyName ~= 'author' or data[ propertyId ] ) then return end local statements = getBestStatements( entityId, propertyId ) if propertyName == 'author' then data[ propertyId ] = true end local lang = getLangCode( data.lang ) or i18nDefaultLanguage if propertyId == 'P1680' then -- if there is a default language for _, statement in pairs( statements ) do if statement and statement.mainsnak and statement.mainsnak.datavalue and statement.mainsnak.datavalue.value and statement.mainsnak.datavalue.value.language == lang then --found default language string appendImpl( statement.mainsnak.datavalue, statement.qualifiers, data, propertyName, options ) return end end end for _, statement in pairs( statements ) do if statement and statement.mainsnak and statement.mainsnak.datavalue then appendImpl( statement.mainsnak.datavalue, statement.qualifiers or {}, data, propertyName, options ) if propertyName == 'publication-id' and statement.qualifiers then data[ 'publication-qualifiers' ] = statement.qualifiers end end end end ---@param claims table<number, statement> ---@param qualifierPropertyId string ---@param result table ---@param resultPropertyId string ---@param options table ---@return void local function appendQualifiers( claims, qualifierPropertyId, result, resultPropertyId, options ) -- do not populate twice if not claims or result[ resultPropertyId ] then return end for _, claim in pairs( claims ) do if claim.qualifiers and claim.qualifiers[ qualifierPropertyId ] then ---@type table<number, snak> local propertyQualifiers = claim.qualifiers[ qualifierPropertyId ] for _, qualifier in pairs( propertyQualifiers ) do if qualifier and qualifier.datavalue then appendImpl( qualifier.datavalue, nil, result, resultPropertyId, options ) end end end end end ---@param entityId string ---@param propertyId string ---@param value any ---@return table<number, statement> local function findClaimsByValue( entityId, propertyId, value ) local result = {} local claims = getAllStatements( entityId, propertyId ) for _, claim in pairs( claims ) do if ( claim.mainsnak and claim.mainsnak.datavalue ) then local datavalue = claim.mainsnak.datavalue if ( datavalue.type == "string" and datavalue.value == value ) or ( datavalue.type == "wikibase-entityid" and datavalue.value[ "entity-type" ] == "item" and tostring( datavalue.value.id ) == value ) then table.insert( result, claim ) end end end return result end ---@param entityId string ---@param typeEntityId string ---@return boolean local function isInstanceOf( entityId, typeEntityId ) return findClaimsByValue( entityId, 'P31', typeEntityId )[ 1 ] ~= nil end ---@param entityId string ---@param typeEntityIds string[] ---@return string ---@todo Rewrite local function getFirstType( entityId, typeEntityIds ) for _, typeEntityId in pairs( typeEntityIds ) do if isInstanceOf( entityId, typeEntityId ) then return typeEntityId end end return nil end ---@param snaks snaks ---@param data source ---@param map map ---@return void local function populateDataFromSnaks( snaks, data, map ) for _, row in ipairs( map ) do local parameterName, propertyIds = row.name, row.ids for _, propertyId in pairs( propertyIds ) do if not data[ parameterName ] and snaks[ propertyId ] then local options = {} if propertyId == 'P888' then options = { format = function( id ) return 'http://www.jstor.org/stable/' .. id end } end for _, snak in pairs( snaks[ propertyId ] ) do if snak and snak.datavalue then appendImpl( snak.datavalue, {}, data, parameterName, options ) end end end end end end ---@param entityId string | nil ---@param data source ---@param map map ---@return void local function populateDataFromEntity( entityId, data, map ) if not data.title then if not isEmpty( entityId ) then local optionsAsLinks = { format = function( text ) return { id = entityId, label = text } end } appendEntitySnaks( entityId, 'P1476', data, 'title', optionsAsLinks ) else appendEntitySnaks( entityId, 'P1476', data, 'title', {} ) end appendEntitySnaks( entityId, 'P1680', data, 'subtitle', {} ) end local bookSeriesStatements = getBestStatements( entityId, 'P361' ) for _, statement in pairs( bookSeriesStatements ) do if statement and statement.mainsnak and statement.mainsnak.datavalue and statement.mainsnak.datavalue.value and statement.mainsnak.datavalue.value.id then local possibleBookSeriesEntityId = statement.mainsnak.datavalue.value.id if isInstanceOf( possibleBookSeriesEntityId, 'Q277759' ) then appendImpl_toTable( data, 'bookSeries' ) table.insert( data.bookSeries, { id = possibleBookSeriesEntityId } ) appendQualifiers( { statement }, 'P478', data, 'bookSeriesVolume', {} ) appendQualifiers( { statement }, 'P433', data, 'bookSeriesIssue', {} ) end end end for _, row in ipairs( map ) do local parameterName, propertyIds = row.name, row.ids for _, propertyId in pairs( propertyIds ) do local options = {} if propertyId == 'P888' then options = { format = function( id ) return 'http://www.jstor.org/stable/' .. id end } end appendEntitySnaks( entityId, propertyId, data, parameterName, options ) end end end ---@param data source ---@return void local function expandPublication( data ) if not data[ 'publication-id' ] then return end local publicationId = getSingle( data[ 'publication-id' ] ) data.publication = {} for key, value in pairs( data ) do if not string.match( key, '^publication-' ) then data.publication[ key ] = value end end data.publication.sourceId = publicationId data.publication.title = data[ 'publication-title' ] data.publication.subtitle = data[ 'publication-subtitle' ] if data[ 'publication-qualifiers' ] then populateDataFromSnaks( data[ 'publication-qualifiers' ], data.publication, PUBLICATION_PROPERTY_MAP ) end populateDataFromEntity( publicationId, data.publication, PUBLICATION_PROPERTY_MAP ) if type( data.publication.title ) == 'table' and data.publication.title[ 1 ] then data.publication.title = data.publication.title[ 1 ] end if type( data.publication.subtitle ) == 'table' and data.publication.subtitle[ 1 ] then data.publication.subtitle = data.publication.subtitle[ 1 ] end for key, value in pairs( data.publication ) do if key ~= 'sourceId' and key ~= 'title' and key ~= 'subtitle' and key ~= 'url' and not data[ key ] then data[ key ] = value end end end ---@param data source ---@return void local function expandBookSeries( data ) local bookSeries = data.bookSeries if not bookSeries then return end -- use only first one if type( bookSeries ) == 'table' and bookSeries[ 1 ] and bookSeries[ 1 ].id then data.bookSeries = bookSeries[ 1 ] bookSeries = data.bookSeries end if not bookSeries or not bookSeries.id then return end appendEntitySnaks( bookSeries.id, 'P123', data, 'publisher', {} ) appendEntitySnaks( bookSeries.id, 'P291', data, 'place', {} ) appendEntitySnaks( bookSeries.id, 'P236', data, 'issn', {} ) end ---@param entityId string ---@return string | nil local function getNormativeTitle( entityId ) local possibleTypeIds = {} for typeId, _ in pairs( NORMATIVE_DOCUMENTS ) do table.insert( possibleTypeIds, typeId ) end local foundTypeId = getFirstType( entityId, possibleTypeIds ) if foundTypeId then return NORMATIVE_DOCUMENTS[ foundTypeId ] end return nil end ---@param urls table<number, string> | string ---@param text string ---@return string local function wrapInUrl( urls, text ) local url = getSingle( urls ) if string.sub( url, 1, 1 ) == ':' then return '[[' .. url .. '|' .. text .. ']]' else return '[' .. url .. ' ' .. text .. ']' end end ---@param entityId string ---@param lang string ---@return string local function getElementLink( entityId, lang ) local sitelink = getSitelink( entityId, nil ) if sitelink then return ':' .. sitelink end if lang ~= 'mul' then -- link to entity in source language sitelink = getSitelink( entityId, lang .. 'wiki' ) if sitelink then return ':' .. lang .. ':' .. sitelink end end return ':d:' .. entityId end ---@param entityId string ---@param lang string ---@return string local function getLabel( entityId, lang ) local wbStatus, label = pcall( mw.wikibase.getLabelByLang, entityId, lang ) if not wbStatus then return '' end if label and label ~= '' then return label end wbStatus, label = pcall( mw.wikibase.getLabel, entityId ) if not wbStatus then return '' end return label or '' end ---@param lang string ---@param entityId string ---@param customTitle string ---@param options table local function renderLink( lang, entityId, customTitle, options ) if not entityId then error( 'entityId is not specified' ) end if type( entityId ) ~= 'string' then error( 'entityId is not string, but ' .. type( entityId ) ) end if type( customTitle or '' ) ~= 'string' then error( 'customTitle is not string, but ' .. type( customTitle ) ) end local title = customTitle -- ISO 4 if isEmpty( title ) then local propertyStatements = getBestStatements( entityId, 'P1160' ) for _, claim in pairs( propertyStatements ) do if ( claim and claim.mainsnak and claim.mainsnak.datavalue and claim.mainsnak.datavalue.value and claim.mainsnak.datavalue.value.language == lang ) then title = claim.mainsnak.datavalue.value.text -- mw.log( 'Got title of ' .. entityId .. ' from ISO 4 claim: «' .. title .. '»' ) break end end end -- official name P1448 -- short name P1813 if isEmpty( title ) and options.short then local propertyStatements = getBestStatements( entityId, 'P1813' ) for _, claim in pairs( propertyStatements ) do if ( claim and claim.mainsnak and claim.mainsnak.datavalue and claim.mainsnak.datavalue.value and claim.mainsnak.datavalue.value.language == lang ) then title = claim.mainsnak.datavalue.value.text -- mw.log( 'Got title of ' .. entityId .. ' from short name claim: «' .. title .. '» (' .. lang .. ')' ) break end end end -- person name P1559 -- labels if isEmpty( title ) then title = getLabel( entityId, lang ) -- mw.log( 'Got title of ' .. entityId .. ' from label: «' .. title .. '» (' .. lang .. ')' ) end local actualText = title or '\'\'(untranslated)\'\'' local link = getElementLink( entityId, lang ) return wrapInUrl( link, actualText ) end ---@param lang string ---@param value value ---@param options options ---@return string local function asString( lang, value, options ) if type( value ) == 'string' then return options.format( value ) end if type( value ) ~= 'table' then return options.format( '(unknown type)' ) end if value.id then -- this is link if type( value.label or '' ) ~= 'string' then mw.logObject( value, 'error value' ) error( 'label of table value is not string but ' .. type( value.label ) ) end local title if options.preferids then title = value.id elseif options.nolinks then title = value.label or getLabel( value.id, lang ) else title = renderLink( lang, value.id, value.label, options ) end if title == '' then title = "''(untranslated title)''" end return options.format( title ) end local resultList = {} for _, tableValue in pairs( value ) do table.insert( resultList, asString( lang, tableValue, options ) ) end return mw.text.listToText( resultList, options.separator, options.conjunction ) end ---@param entityId string ---@param data source ---@return source local function populateSourceDataImpl( entityId, data, map ) local wsLink = getSitelink( entityId, 'ruwikisource' ) if wsLink and not mw.ustring.gmatch( wsLink, 'Категория:' ) then data.url = ":ru:s:" .. wsLink end populateDataFromEntity( entityId, data, map ) local normativeTitle = getNormativeTitle( entityId ) if normativeTitle then local y, m, d = mw.ustring.match( getSingle( data.dateOfCreation ) , "(%-?%d+)%-(%d+)%-(%d+)T" ) y, m, d = tonumber( y ),tonumber( m ), tonumber( d ) local title = asString( 'ru', data.title, options_commas_nolinks ) local docNumber = getSingle( data.docNumber ) data.title = { normativeTitle .. " от&nbsp;" .. tostring( d ) .. "&nbsp;" .. monthGen[ m ] .. " " .. tostring( y ) .. "&nbsp;г." .. ( docNumber and ( " №&nbsp;" .. docNumber ) or '' ) .. ' «' .. title.. '»' } end if not data.title then local lang = getLangCode( data.lang ) or i18nDefaultLanguage local label = getLabel( entityId, lang ) if label ~= '' then data.title = { label } end end return data end ---@param entityId string ---@param propertyId string ---@param data source ---@return void local function expandSpecialsQualifiers( entityId, propertyId, data ) local statements = getBestStatements( entityId, propertyId ) for _, statement in pairs( statements ) do populateDataFromSnaks( statement.qualifiers or {}, data, PROPERTY_MAP ) end end ---Expand special types of references when additional data could be found in OTHER entity properties ---@param data source ---@return void local function expandSpecials( data ) if not data.entityId then return end if data.sourceId == 'Q36578' then -- Gemeinsame Normdatei -- specified by P227 appendEntitySnaks( data.entityId, 'P227', data, 'part', { format = function(gnd ) return 'Record #' .. gnd; end } ) appendEntitySnaks( data.entityId, 'P227', data, 'url', { format = function(gnd ) return 'http://d-nb.info/gnd/' .. gnd .. '/'; end } ) data.year = '2012—2016' expandSpecialsQualifiers( data.entityId, 'P227', data ) elseif data.sourceId == 'Q15222191' then -- BNF -- specified by P268 appendEntitySnaks( data.entityId, 'P268', data, 'part', { format = function(id ) return 'Record #' .. id; end } ) appendEntitySnaks( data.entityId, 'P268', data, 'url', { format = function(id ) return 'http://catalogue.bnf.fr/ark:/12148/cb' .. id; end } ) expandSpecialsQualifiers( data.entityId, 'P268', data ) elseif data.sourceId == 'Q54919' then -- VIAF -- specified by P214 appendEntitySnaks( data.entityId, 'P214', data, 'part', { format = function(id ) return 'Record #' .. id; end } ) appendEntitySnaks( data.entityId, 'P214', data, 'url', { format = function(id ) return 'https://viaf.org/viaf/' .. id; end } ) expandSpecialsQualifiers( data.entityId, 'P214', data ) else -- generic property search for _, sourceClaim in pairs( getBestStatements( data.sourceId, 'P1687' ) ) do if sourceClaim.mainsnak.snaktype == 'value' then local sourcePropertyId = sourceClaim.mainsnak.datavalue.value.id for _, sourcePropertyClaim in pairs( getBestStatements( sourcePropertyId, 'P1630' ) ) do if sourcePropertyClaim.mainsnak.snaktype == 'value' then appendEntitySnaks( data.entityId, sourcePropertyId, data, 'url', { format = function( id ) return mw.ustring.gsub( mw.ustring.gsub( sourcePropertyClaim.mainsnak.datavalue.value, '$1', id ), ' ', '%%20' ) end } ) expandSpecialsQualifiers( data.entityId, sourcePropertyId, data ) break end end end end end -- do we have appropriate record in P1433 ? local claims = findClaimsByValue( currentEntityId, 'P1343', data.sourceId ) if claims and #claims ~= 0 then for _, claim in pairs( claims ) do populateDataFromSnaks( claim.qualifiers, data, PROPERTY_MAP ) populateDataFromEntity( data.sourceId, data, PROPERTY_MAP ) end end end ---@param text string ---@param tip string ---@return string local function toTextWithTip( text, tip ) return '<span title="' .. tip .. '" style="border-bottom: 1px dotted; cursor: help; white-space: nowrap">' .. text .. '</span>' end ---@param lang string ---@param placeId string ---@return string local function getPlaceName( placeId, lang ) -- ГОСТ Р 7.0.12—2011 if lang == 'ru' then if placeId == 'Q649' then return toTextWithTip( 'М.', 'Москва' ); end if placeId == 'Q656' then return toTextWithTip( 'СПб.', 'Санкт-Петербург' ); end if placeId == 'Q891' then return toTextWithTip( 'Н. Новгород', 'Нижний Новгород' ); end if placeId == 'Q908' then return toTextWithTip( 'Ростов н/Д.', 'Ростов-на-Дону' ); end end return nil end ---@param data source ---@param lang string ---@return void local function preprocessPlace( data, lang ) if not data.place then return end ---@type table<number, string> local newPlace = {} for index, place in pairs( data.place ) do if place.id then local newPlaceStr = getPlaceName( place.id, lang ) if newPlaceStr then newPlace[ index ] = newPlaceStr else newPlace[ index ] = getLabel( place.id, lang ) end else newPlace[ index ] = place end end data.place = newPlace end ---@param entityId string ---@param lang string ---@param providedLabel string | nil ---@param options options ---@return string local function getPersonNameAsLabel( entityId, lang, providedLabel, options ) -- would custom label provided we don't need to check entity at all if not isEmpty( providedLabel ) then return options.format( providedLabel ) end if lang == 'mul' then lang = i18nDefaultLanguage end ---@type string | nil local personName = getLabel( entityId, lang ) if isEmpty( personName ) then return '\'\'(not translated to ' .. lang .. ')\'\'' end if not isInstanceOf( entityId, 'Q5' ) then return personName end return options.format( personName ) end ---@param entityId string ---@param lang string ---@param customLabel string | nil ---@param options options ---@return string local function getPersonNameAsWikitext( entityId, lang, customLabel, options ) local personName = getPersonNameAsLabel( entityId, lang, customLabel, options ) local link = getElementLink( entityId, lang ) return wrapInUrl( link, personName ) end ---@param value value ---@param lang string ---@param options options ---@return string local function getPeopleAsWikitext( value, lang, options ) if type( value ) == 'string' then return options.format( value ) elseif type( value ) == 'table' then if value.id then -- this is link if options.preferids then return tostring( value.id ) else if options.nolinks then return getPersonNameAsLabel( value.id, lang, value.label, options ) else return getPersonNameAsWikitext( value.id, lang, value.label, options ) end end end local maxAuthors = 10 -- need some restrictions, as some publications have enormous amount of authors (e.g. 115 authors of Q68951544) local resultList = {} for _, tableValue in pairs( value ) do local nextWikitext = getPeopleAsWikitext( tableValue, lang, options ) if not isEmpty( nextWikitext ) then table.insert( resultList, nextWikitext ) if #resultList == maxAuthors + 1 then -- keep one more to indicate that there are too many break end end end local resultWikitext = '' for i, wikitext in pairs( resultList ) do if i == maxAuthors + 1 then resultWikitext = resultWikitext .. ( i18nEtAl[ lang ] or i18nEtAlDefault ) break end if i ~= 1 then resultWikitext = resultWikitext .. ', ' end resultWikitext = resultWikitext .. wikitext end return resultWikitext end return '' -- options.format( '(unknown type)' ) end ---@param lang string ---@param data source ---@return string local function generateAuthorLinks( lang, data ) local result = '' if data.author then result = getPeopleAsWikitext( data.author, lang, options_commas_authors ) result = '<i class="wef_low_priority_links">' .. result .. '</i> ' end return result end ---@param lang string ---@param data source ---@param conjunction string ---@param propertyName string ---@param urlPropertyName string? ---@return string local function appendProperty( lang, data, conjunction, propertyName, urlPropertyName ) if not data[ propertyName ] then return '' end local out if urlPropertyName and data[ urlPropertyName ] then out = wrapInUrl( data[ urlPropertyName ], asString( lang, data[ propertyName ], options_commas_nolinks ) ) else out = asString( lang, data[ propertyName ], options_commas ) end if not out or out == '' then return '' end return conjunction .. out end ---@param lang string ---@param data source ---@return string local function appendTitle( lang, data ) local conjunction = '' local result = '' if data.part then result = result .. appendProperty( lang, data, '', 'part', 'parturl' ) conjunction = ' // ' end return result .. appendProperty( lang, data, conjunction, 'title', 'url' ) end ---@param lang string ---@return string local function appendLanguage( lang ) if lang == i18nDefaultLanguage then return '' end ---@type { getRefHtml: ( fun( lang: string ): string ), list_ref: ( fun( frame: frame ): string ) } local langs = require( 'Module:Languages' ) return langs.list_ref( p.currentFrame:newChild{ args = { lang } } ) end ---@param lang string ---@param data source ---@return string local function appendSubtitle( lang, data ) return appendProperty( lang, data, ': ', 'subtitle', nil ) end ---@param lang string ---@param data source ---@return string local function appendOriginalTitle( lang, data ) return appendProperty( lang, data, ' = ', 'originaltitle', nil ) end ---@param lang string ---@param data source ---@return string local function appendPublication( lang, data ) if not data.publication then return '' end local result = ' // ' .. asString( lang, data.publication.title, options_commas_it_short ) if data.publication.subtitle and data.publication.subtitle ~= '' then result = result .. ': ' .. asString( lang, data.publication.subtitle, options_commas_it_short ) end return result end ---@param lang string ---@param data source ---@return string local function appendEditor( lang, data ) if not data.editor and not data.translator then return '' end local result = ' / ' if data.editor then local prefix = i18nEditors[ lang ] or i18nEditors[ i18nDefaultLanguage ] result = result .. prefix .. getPeopleAsWikitext( data.editor, lang, options_commas_responsible ) if data.translator then result = result .. ', ' end end if data.translator then local prefix = i18nTranslators[ lang ] or i18nTranslators[ i18nDefaultLanguage ] result = result .. prefix .. getPeopleAsWikitext( data.translator, lang, options_commas_responsible ) end return result end ---@param lang string ---@param data source local function appendEdition( lang, data ) return appendProperty( lang, data, ' — ', 'edition', nil ) end ---@param lang string ---@param data source ---@return string local function appendPublicationData( lang, data ) if not data.place and not data.publisher and not data.year then return '' end local result = ' — ' if data.place then result = result .. asString( lang, data.place, options_commas_short ) if data.publisher or data.year then result = result .. ': ' end end if data.publisher then result = result .. asString( lang, data.publisher, options_commas_short ) if data.year then result = result .. ', ' end end if data.year then result = result .. asString( lang, data.year, options_commas ) end result = result .. '.' return result end ---@param lang string ---@param data source ---@return string local function appendVolumeAndIssue( lang, data ) if not data.volume and not data.issue then return '' end local result = ' — ' local letter_vol = i18nVolume[ lang ] or i18nVolume[ i18nDefaultLanguage ] local letter_iss = i18nIssue[ lang ] or i18nIssue[ i18nDefaultLanguage ] if data.volume then result = result .. appendProperty( lang, data, letter_vol .. '&nbsp;', 'volume', nil ) result = result ..appendProperty( lang, data, ', ' .. letter_iss .. '&nbsp;', 'issue', nil ) else result = result .. appendProperty( lang, data, letter_iss .. '&nbsp;', 'issue', nil ) end result = result .. '.' return result end ---@param lang string ---@param data source ---@return string local function appendPages( lang, data ) if not data.pages then return '' end local letter = i18nPages[ lang ] or i18nPages[ i18nDefaultLanguage ] local strPages = asString( lang, data.pages, options_commas ) strPages = mw.ustring.gsub( strPages, '[-—]', '—' ) return ' — ' .. letter .. '&nbsp;' .. strPages .. '.' end ---@param lang string ---@param data source ---@return string local function appendNumberOfPages( lang, data ) if not data.numberOfPages then return '' end local letter = i18nNumberOfPages[ lang ] or i18nNumberOfPages[ i18nDefaultLanguage ] return appendProperty( lang, data, ' — ', 'numberOfPages', nil ) .. '&nbsp;' .. letter end ---@param lang string ---@param data source ---@return string local function appendBookSeries( lang, data ) if not data.bookSeries then return '' end local result = appendProperty( lang, data, ' — (', 'bookSeries', nil ) if data.bookSeriesVolume or data.bookSeriesIssue then result = result .. '; ' local letter_vol = i18nVolume[ lang ] or i18nVolume[ i18nDefaultLanguage ] local letter_iss = i18nIssue[ lang ] or i18nIssue[ i18nDefaultLanguage ] if data.bookSeriesVolume then result = result .. appendProperty( lang, data, letter_vol .. '&nbsp;', 'bookSeriesVolume', nil ) result = result .. appendProperty( lang, data, ', ' .. letter_iss .. '&nbsp;', 'bookSeriesIssue', nil ) else result = result .. appendProperty( lang, data, letter_iss .. '&nbsp;', 'bookSeriesIssue', nil ) end end result = result .. ')' return result end ---@param lang string ---@param data source ---@return string local function appendTirage( lang, data ) if not data.tirage then return '' end local tirageTemplate = i18nTirage[ lang ] or i18nTirage[ i18nDefaultLanguage ] ---@type options local optionsTirage = { separator = '; ', conjunction = '; ', format = function( _data ) return tostring( mw.ustring.format( tirageTemplate, _data ) ) end, short = false, nolinks = false, preferids = false, } return ' — ' .. asString( lang, data.tirage, optionsTirage ) end ---@param lang string ---@param value string | nil ---@param options options ---@param prefix string? ---@return string local function appendIdentifier( lang, value, options, prefix ) if not value then return '' end return ' — ' .. ( prefix or '' ) .. asString( lang, value, options ) end ---@param result string ---@param lang string ---@param data source ---@return string local function wrapSourceId( result, lang, data ) if not data.sourceId then return result end local citeType = data.type and asString( lang, data.type, options_citetypes ) or 'citetype_unknown' return '<span class="wikidata_cite ' .. citeType .. '" data-entity-id="' .. data.sourceId .. '">' .. result .. '</span>' end ---@param data source ---@return string local function appendAccessDate( data ) if not data.accessdate then return '' end local date = getSingle( data.accessdate ) local pattern = "(%-?%d+)%-(%d+)%-(%d+)T" local y, m, d = mw.ustring.match( date, pattern ) y, m, d = tonumber( y ), tonumber( m ), tonumber( d ) local date_str = ( d > 0 and ' ' .. tostring( d ) or '' ) .. ( m > 0 and ' ' .. monthGen[ m ] or '' ) .. ( y > 0 and ' ' .. tostring( y ) or '' ) return " <small>Проверено" .. date_str .. ".</small>" end ---@param data source ---@param lang string ---@return void local function populateUrl( data, lang ) if data.sourceId and not data.url then local sitelink = getSitelink( data.sourceId, lang .. 'wikisource' ) if sitelink then data.url = ':' .. lang .. ':s:' .. sitelink end end end ---@param data source ---@return void local function populateYear( data ) if not data.year and data.dateOfPublication then local date = getSingle( data.dateOfPublication ) data.year = mw.ustring.sub( date, 2, 5 ) end if not data.year and data.dateOfCreation then local date = getSingle( data.dateOfCreation ) data.year = mw.ustring.sub( date, 2, 5 ) end end ---@param data source ---@return void local function populateTitle( data ) data.title = data.title or getSingle( data.url ) end ---@param data source ---@return string local function renderSource( data ) local lang = getLangCode( data.lang ) or i18nDefaultLanguage preprocessPlace( data, lang ) populateUrl( data, lang ) populateTitle( data ) if not data.title then return '' end populateYear( data ) local result = generateAuthorLinks( lang, data ) result = result .. appendTitle( lang, data ) result = result .. appendLanguage( lang ) result = result .. appendSubtitle( lang, data ) result = result .. appendOriginalTitle( lang, data ) result = result .. appendPublication( lang, data ) result = result .. '<span class="wef_low_priority_links">' result = result .. appendEditor( lang, data ) -- Might take current editor instead of actual. Use with caution result = result .. appendEdition( lang, data ) result = result .. appendPublicationData( lang, data ) result = result .. appendVolumeAndIssue( lang, data ) result = result .. appendPages( lang, data ) result = result .. appendNumberOfPages( lang, data ) result = result .. appendBookSeries( lang, data ) result = result .. appendTirage( lang, data ) result = result .. appendIdentifier( lang, data.isbn, options_commas, 'ISBN ' ) result = result .. appendIdentifier( lang, data.issn, options_issn, 'ISSN ' ) result = result .. appendIdentifier( lang, data.doi, options_doi, nil ) result = result .. appendIdentifier( lang, data.pmid, options_pmid, nil ) result = result .. appendIdentifier( lang, data.arxiv, options_arxiv, nil ) result = result .. appendAccessDate( data ) result = result .. '</span>' return wrapSourceId( result, lang, data ) end ---@param data source Данные в простом формате, согласованном с модулями формирования библиографического описания ---@param snaks snaks ---@return string | nil local function renderReferenceImpl( data, snaks ) -- не показывать источники с "импортировано из" if snaks.P143 then return nil end -- забрать данные из reference populateDataFromSnaks( snaks or {}, data, PROPERTY_MAP ) data.sourceId = getSingle( data.sourceId ) populateDataFromEntity( data.sourceId, data, PROPERTY_MAP ) expandSpecials( data ) populateSourceDataImpl( data.sourceId, data, PROPERTY_MAP ) expandPublication( data ) expandBookSeries( data ) if next( data ) == nil then return nil end local rendered = renderSource( data ) if mw.ustring.len( rendered ) == 0 then return nil end if data.ref then local anchorValue = 'CITEREF' .. data.ref .. ( coalesce( { data[ 'ref-year' ], data.year } ) or '' ) rendered = '<span class="citation" id="' .. mw.uri.anchorEncode( anchorValue ) .. '">' .. rendered .. '</span>' end return rendered end ---@param frame frame ---@param currentEntityId string | { id: string } ---@param reference table{ snaks: snaks } ---@return string | nil function p.renderSource( frame, currentEntityId, reference ) reference = reference or { snaks = {} } p.currentFrame = frame local data = getFilledArgs( frame.args or {} ) populateDataFromSnaks( reference.snaks, data, PROPERTY_MAP ) data.sourceId = getSingle( data.sourceId ) if not currentEntityId then data.entityId = mw.wikibase.getEntityIdForCurrentPage() elseif type( currentEntityId ) == 'string' then data.entityId = currentEntityId elseif type( currentEntityId ) == 'table' and currentEntityId.id then data.entityId = currentEntityId.id end ---@type string local rendered = renderReferenceImpl( data, reference.snaks or {} ) if not rendered then return '' end return rendered end ---@param frame frame ---@param currentEntityId string ---@param reference table ---@return string function p.renderReference( frame, currentEntityId, reference ) local rendered = p.renderSource( frame, currentEntityId, reference ) if not rendered or rendered == '' then return '' end -- Про выбор алгоритма хеширования см. [[Модуль:Hash]]. Знак подчёркивания в начале позволяет -- исключить ошибку, когда имя сноски — чисто числовое значение, каковыми иногда бывают хеши. return frame:extensionTag( 'ref', rendered, { name = '_' .. mw.hash.hashValue( 'fnv164', rendered ) } ) .. '[[Category:Википедия:Статьи с источниками из Викиданных]]' end ---@param frame frame ---@return string | nil function p.testPersonNameToAuthorName( frame ) return personNameToAuthorName( frame.args[ 1 ] ) end ---@param frame frame ---@return string | nil function p.testPersonNameToResponsibleName( frame ) return personNameToResponsibleName( frame.args[ 1 ] ) end return p 752a204827a41ecd6cf518bdb22da12718bca2ec Модуль:WikidataSelectors 828 141 325 324 2024-08-10T15:21:03Z DuOfOrl 5 1 версия импортирована Scribunto text/plain local i18n = { ["errors"] = { ["rank-not-valid"] = "Некорретное значение приоритета (rank)", ["cant-parse-condition"] = "Не удалось разобрать условие" } } local validRanks = { 'best', 'preferred', 'normal', 'deprecated' } --[[ Internal function for error message Input: key in errors table Output: error message ]] local function throwError( key ) error( i18n.errors[key] ) end local p = {} --[[ Load property and filter statements Input: entityId, selector string Output: filtered statements table ]] function p.load( entityId, propertySelector ) local propertyId = mw.ustring.match( propertySelector, '^[Pp]%d+' ) if not propertyId then return nil end propertyId = string.upper( propertyId ) local allStatements = {} allStatements[ propertyId ] = mw.wikibase.getAllStatements( entityId, propertyId ) return p.filter( allStatements, propertySelector ) end --[[ Parse selectors and filter statements Input: statements table, selector string Output: filtered statements table ]] function p.filter( allClaims, propertySelector ) propertySelector = mw.text.trim( propertySelector ) -- Get property ID from selector local propertyId = mw.ustring.match( propertySelector, '^[Pp]%d+' ) if not propertyId then propertyId = '' end local initPos = #propertyId + 1 propertyId = string.upper( propertyId ) if ( not allClaims ) then return nil end local allPropertyClaims = allClaims[propertyId] if ( not allPropertyClaims ) then return nil end -- Gathering rules local rules = p.matchSelectors( propertySelector, initPos ) -- If there is no rank filter, than default rank is 'best' local isRanked = false for i, subRules in ipairs( rules ) do for j, rule in ipairs( subRules ) do if rule['type'] == 'rank' then isRanked = true break end end end if not isRanked then table.insert( rules, 1, { { type = 'rank', value = 'best' } } ) end -- Execute rules allPropertyClaims = p.applyRules( allPropertyClaims, rules ) return allPropertyClaims end --[[ Match and gather selector rules Input: string with selectors rules, start position Output: rules table ]] function p.matchSelectors( selectorsString, initPos ) local rules = {} local rawRulePattern = '^%s*%[%s*[^%[%]]+%s*%]%s*' local rulePattern = '^%s*%[%s*([^%[%]]+)%s*%]%s*$' if not initPos then initPos = 1 end local rawRule = mw.ustring.match( selectorsString, rawRulePattern, initPos ) while rawRule do initPos = initPos + #rawRule rule = mw.ustring.match( rawRule, rulePattern ) rule = mw.text.trim( rule ) local subRules = mw.text.split( rule, '%s*,%s*' ) local commands = {} local comm for i, subRule in ipairs( subRules ) do local isInversed = false if mw.ustring.match( subRule, '^!' ) then isInversed = true subRule = mw.ustring.match( subRule, '^!%s*(.+)$' ) end -- p123[1] if mw.ustring.match( subRule, '^%d+$' ) then table.insert( commands, { type = 'position', value = subRule, inversed = isInversed } ) -- p123[rank:preferred] elseif mw.ustring.match( subRule, '^rank%s*:%s*(%a+)$' ) then rank = mw.ustring.match( subRule, '^rank%s*:%s*(%a+)$' ) table.insert( commands, { type = 'rank', value = rank, inversed = isInversed } ) -- p123[language:xx] elseif mw.ustring.match( subRule, '^language%s*:%s*([%a%-]+)$' ) then value = mw.ustring.match( subRule, '^language%s*:%s*([%a%-]+)$' ) table.insert( commands, { type = 'language', value = value, inversed = isInversed } ) -- p123[language!:xx] elseif mw.ustring.match( subRule, '^language%s*!:%s*([%a%-]+)$' ) then value = mw.ustring.match( subRule, '^language%s*!:%s*([%a%-]+)$' ) table.insert( commands, { type = 'language', value = value, inversed = not isInversed } ) -- p123[min] elseif mw.ustring.match( subRule, '^min$' ) then table.insert( commands, { type = 'value_min' } ) -- p123[max] elseif mw.ustring.match( subRule, '^max$' ) then table.insert( commands, { type = 'value_max' } ) -- p123[min:p456] elseif mw.ustring.match( subRule, '^min%s*:%s*[Pp]%d+$' ) then value = mw.ustring.match( subRule, ':%s*([Pp]%d+)$' ) table.insert( commands, { type = 'qualifier_min', qualifier = value } ) -- p123[max:p456] elseif mw.ustring.match( subRule, '^max%s*:%s*[Pp]%d+$' ) then value = mw.ustring.match( subRule, ':%s*([Pp]%d+)$' ) table.insert( commands, { type = 'qualifier_max', qualifier = value } ) -- p123[unit:q789] elseif mw.ustring.match( subRule, '^unit%s*:%s*[^%[%],:]+$' ) then value = mw.ustring.match( subRule, ':%s*([^%[%],:]+)$' ) table.insert( commands, { type = 'unit', value = value, inversed = isInversed } ) -- p123[unit!:q789] elseif mw.ustring.match( subRule, '^unit%s*!:%s*[^%[%],:]+$' ) then value = mw.ustring.match( subRule, '!:%s*([^%[%],:]+)$' ) table.insert( commands, { type = 'unit', value = value, inversed = not isInversed } ) -- p123[p456] elseif mw.ustring.match( subRule, '^[Pp]%d+$' ) then qualifier = mw.ustring.match( subRule, '^[Pp]%d+' ) table.insert( commands, { type = 'qualifier', qualifier = qualifier, value = nil, inversed = isInversed } ) -- p123[p456:q789] elseif mw.ustring.match( subRule, '^[Pp]%d+%s*:%s*[^%[%],:]+$' ) then qualifier = mw.ustring.match( subRule, '^([Pp]%d+)%s*:?' ) value = mw.ustring.match( subRule, ':%s*([^%[%],:]+)$' ) table.insert( commands, { type = 'qualifier', qualifier = qualifier, value = value, inversed = isInversed } ) -- p123[p456!:q789] elseif mw.ustring.match( subRule, '^[Pp]%d+%s*!:%s*[^%[%],:]+$' ) then qualifier = mw.ustring.match( subRule, '^([Pp]%d+)%s*!:?' ) value = mw.ustring.match( subRule, '!:%s*([^%[%],:]+)$' ) table.insert( commands, { type = 'qualifier', qualifier = qualifier, value = value, inversed = not isInversed } ) -- p123[q456] elseif mw.ustring.match( subRule, '^[Qq]%d+$' ) then value = mw.ustring.match( subRule, '^[Qq]%d+' ) table.insert( commands, { type = 'value', value = value, inversed = isInversed } ) else throwError( 'cant-parse-condition' ) end end if #commands then table.insert( rules, commands ) end rawRule = mw.ustring.match( selectorsString, rawRulePattern, initPos ) end return rules end --[[ Intercept statements with selector rules Input: statements table, selector rules Output: filtered statements table ]] function p.applyRules( claims, rules ) for i, subRules in ipairs( rules ) do local newClaims = {} for j, rule in ipairs( subRules ) do if rule['type'] == 'rank' then table.insert( newClaims, p.filterByRank( claims, rule['value'], rule['inversed'] ) ) elseif rule['type'] == 'language' then table.insert( newClaims, p.filterByLanguage( claims, rule['value'], rule['inversed'] ) ) elseif rule['type'] == 'unit' then table.insert( newClaims, p.filterByUnit( claims, rule['value'], rule['inversed'] ) ) elseif rule['type'] == 'position' then table.insert( newClaims, p.filterByPosition( claims, rule['value'], rule['inversed'] ) ) elseif rule['type'] == 'qualifier' then table.insert( newClaims, p.filterByQualifier( claims, rule['qualifier'], rule['value'], rule['inversed'] ) ) elseif rule['type'] == 'qualifier_min' then table.insert( newClaims, p.filterUtterByQualifier( claims, rule['qualifier'], true ) ) elseif rule['type'] == 'qualifier_max' then table.insert( newClaims, p.filterUtterByQualifier( claims, rule['qualifier'], false ) ) elseif rule['type'] == 'value' then table.insert( newClaims, p.filterByValue( claims, rule['value'], rule['inversed'] ) ) elseif rule['type'] == 'value_min' then table.insert( newClaims, p.filterUtter( claims, true ) ) elseif rule['type'] == 'value_max' then table.insert( newClaims, p.filterUtter( claims, false ) ) end end claims = {} --[[ Merge all claims TODO: It's not good ]] for j, newSubClaims in ipairs( newClaims ) do for k, newClaim in ipairs( newSubClaims ) do local isNew = true for l, oldClaim in ipairs( claims ) do if oldClaim['id'] == newClaim['id'] then isNew = false break end end if isNew then table.insert( claims, newClaim ) end end end end return claims end --[[ Filter statements by rank Input: claims table, rank value, inversion Output: filtered statements table ]] function p.filterByRank( claims, rank, inversed ) if not inversed then inversed = false end if not rank then rank = 'best' end -- Check if rank value is valid local isValidRank = false for i, validRank in ipairs( validRanks ) do if rank == validRank then isValidRank = true break end end if not isValidRank then throwError( 'rank-not-valid' ) end -- Find the best rank if rank == 'best' then rank = 'normal' -- default rank (don't use deprecated even if it's no more claims) -- If we have at least one preferred rank, mark it as best for i, statement in pairs( claims ) do if (statement.rank == 'preferred') then rank = 'preferred' break end end end local resultClaims = {}; for i, statement in pairs( claims ) do if ( statement.rank == rank ) ~= inversed then table.insert( resultClaims, statement ) end end return resultClaims end --[[ Filter statements by language of value Input: claims table, language, inversion Output: filtered statements table ]] function p.filterByLanguage( claims, language, inversed ) if not inversed then inversed = false end local resultClaims = {} local mulStatement = {} for i, statement in ipairs( claims ) do isMatchLanguage = false if statement['mainsnak'] and statement['mainsnak']['datavalue'] and statement['mainsnak']['datavalue']['value'] and statement['mainsnak']['datavalue']['value']['language'] then if statement['mainsnak']['datavalue']['value']['language'] == language then isMatchLanguage = true end if statement['mainsnak']['datavalue']['value']['language'] == 'mul' then mulStatement = statement end end if isMatchLanguage ~= inversed then table.insert( resultClaims, statement ) end end if next(resultClaims) == nil and next(mulStatement) ~= nil then -- if specific language is not found, but there is Q20923490 value table.insert( resultClaims, mulStatement ) end return resultClaims end --[[ Filter statements by unit of value Input: claims table, unit, inversion Output: filtered statements table ]] function p.filterByUnit( claims, unit, inversed ) if not inversed then inversed = false end unit = 'http://www.wikidata.org/entity/' .. string.upper( unit ) local resultClaims = {} for i, statement in ipairs( claims ) do isMatchUnit = false if statement['mainsnak'] and statement['mainsnak']['datavalue'] and statement['mainsnak']['datavalue']['value'] and statement['mainsnak']['datavalue']['value']['unit'] and statement['mainsnak']['datavalue']['value']['unit'] == unit then isMatchUnit = true end if isMatchUnit ~= inversed then table.insert( resultClaims, statement ) break end end return resultClaims end --[[ Filter statements by position Input: claims table, position, inversion Output: filtered statements table ]] function p.filterByPosition( claims, position, inversed ) if not inversed then inversed = false end local resultClaims = {}; for statementPosition, statement in ipairs( claims ) do if ( statementPosition == tonumber( position ) ) ~= inversed then table.insert( resultClaims, statement ) break end end return resultClaims end --[[ Filter statements by qualifier existance or it's value Input: claims table, ID of qualifier's property, qualifier's value, inversion Output: filtered statements table ]] function p.filterByQualifier( claims, qualifierId, value, inversed ) if not inversed then inversed = false end qualifierId = string.upper( qualifierId ) local resultClaims = {} for i, statement in ipairs( claims ) do if statement['qualifiers'] and statement['qualifiers'][qualifierId] then if value == nil then if ( #statement['qualifiers'][qualifierId] > 0 ) ~= inversed then table.insert( resultClaims, statement ) end else local isQualifierFound = false for j, qualifier in ipairs( statement['qualifiers'][qualifierId] ) do if qualifier['datavalue'] then local qualifierValue = qualifier['datavalue']['value'] if qualifier['datavalue']['type'] == 'wikibase-entityid' then qualifierValue = qualifierValue.id value = string.upper( value ) end if qualifierValue == value then isQualifierFound = true break end end end if isQualifierFound ~= inversed then table.insert( resultClaims, statement ) end end elseif inversed then table.insert( resultClaims, statement ) end end return resultClaims end --[[ Filter statements by it's values Input: claims table, value, inversed Output: filtered statements table ]] function p.filterByValue( claims, value, inversed ) inversed = inversed or false local resultClaims = {} for i, statement in ipairs( claims ) do local statementValue if statement['mainsnak'] and statement['mainsnak']['datavalue'] and statement['mainsnak']['datavalue']['type'] then statementValue = statement['mainsnak']['datavalue']['value'] if statement['mainsnak']['datavalue']['type'] == 'quantity' then statementValue = statementValue.amount end if statement['mainsnak']['datavalue']['type'] == 'time' then statementValue = statementValue.time end if statement['mainsnak']['datavalue']['type'] == 'wikibase-entityid' then statementValue = statementValue.id value = string.upper( value ) end end if ( statementValue == value ) ~= inversed then table.insert( resultClaims, statement ) end end return resultClaims end --[[ Find a statement with minimum or maximum value Input: claims table, asc, inversed Output: filtered statements table ]] function p.filterUtter( claims, asc, inversed ) local resultValue = nil for i, statement in ipairs( claims ) do local statementValue if statement['mainsnak'] and statement['mainsnak']['datavalue'] and statement['mainsnak']['datavalue']['type'] then statementValue = statement['mainsnak']['datavalue']['value'] if statement['mainsnak']['datavalue']['type'] == 'quantity' then statementValue = statementValue.amount end if statement['mainsnak']['datavalue']['type'] == 'time' then statementValue = statementValue.time end if statement['mainsnak']['datavalue']['type'] == 'wikibase-entityid' then statementValue = statementValue.id end if not resultValue or ( statementValue < resultValue ) == asc then resultValue = statementValue end end end mw.logObject( resultValue, 'resultValue' ) return p.filterByValue( claims, resultValue, inversed ) end --[[ Find a statement with minimum or maximum qualifier value Input: claims table, qualifierId, asc Output: filtered statements table ]] function p.filterUtterByQualifier( claims, qualifierId, asc ) qualifierId = string.upper( qualifierId ) local resultValue = nil local resultStatement = nil for i, statement in ipairs( claims ) do if not statement['qualifiers'] and not statement['qualifiers'][qualifierId] then if resultStatement == nil then resultStatement = statement end else for _, qualifier in ipairs( statement['qualifiers'][qualifierId] ) do if qualifier['datavalue'] then local qualifierValue = qualifier['datavalue']['value'] if qualifier['datavalue']['type'] == 'quantity' then qualifierValue = qualifierValue.amount end if qualifier['datavalue']['type'] == 'time' then qualifierValue = qualifierValue.time end if qualifier['datavalue']['type'] == 'wikibase-entityid' then qualifierValue = qualifierValue.id end if not resultValue or ( qualifierValue < resultValue ) == asc then resultStatement = statement resultValue = qualifierValue end end end end end return { resultStatement } end return p 0bdff3a63bf171160cdec5c966211fbbf3003880 Модуль:Wikidata/config 828 142 327 326 2024-08-10T15:21:03Z DuOfOrl 5 1 версия импортирована Scribunto text/plain -- Property configuration for Wikidata module return { global = { separator = ',&#32;', conjunction = '&#32;и&#32;', }, presets = { ['catonly'] = { datatype = 'wikibase-item', conjunction = '', invisible = true, ['value-module'] = 'Wikidata/item', ['value-function'] = 'formatCategoryOnly', references = '', category = 'P910', }, ['country'] = { datatype = 'wikibase-item', ['claim-module'] = 'Wikidata/Places', ['claim-function'] = 'formatCountryClaimWithFlag', before = '<ul><li>', separator = '</li><li>', conjunction = '</li><li>', after = '</li></ul>', }, ['from-to'] = { datatype = 'time', ['property-module'] = 'Wikidata/date', ['property-function'] = 'formatDateIntervalProperty', }, ['link'] = { ['value-module'] = 'Wikidata/link', ['value-function'] = 'fromModule', }, ['list'] = { before = '<ul><li>', separator = '</li><li>', conjunction = '</li><li>', after = '</li></ul>', }, ['name'] = { datatype = 'monolingualtext', monolingualLangTemplate = 'lang', separator = '<br>', conjunction = '<br>', }, ['place'] = { datatype = 'wikibase-item', ['claim-module'] = 'Wikidata/Places', ['claim-function'] = 'formatPlaceWithQualifiers', before = '<ul><li>', separator = '</li><li>', conjunction = '</li><li>', after = '</li></ul>', }, ['quantity (date)'] = { datatype = 'quantity', before = '<ul><li>', separator = '</li><li>', conjunction = '</li><li>', after = '</li></ul>', qualifier = 'P585', }, }, datatypes = { commonsMedia = { limit = 1, references = false, size = '274x400px', separator = '<br>', conjunction = '<br>', somevalue = '', ['value-module'] = 'Wikidata/media', ['value-function'] = 'formatCommonsMediaValue', }, ['external-id'] = { references = false, }, ['globe-coordinate'] = { limit = 1, references = false, }, url = { separator = '<br>', conjunction = '<br>', references = false, ['value-module'] = 'Wikidata/url', ['value-function'] = 'formatUrlValue', }, quantity = { siConversion = true } }, properties = { P6 = { datatype = 'wikibase-item', }, P17 = { preset = 'country', }, P18 = { datatype = 'commonsMedia', fixdouble = true, }, P19 = { preset = 'place', separator = ',</li><li>', conjunction = ' или </li><li>', }, P20 = { preset = 'place', separator = ',</li><li>', conjunction = ' или </li><li>', }, P22 = { datatype = 'wikibase-item', conjunction = ' или ' }, P25 = { datatype = 'wikibase-item', conjunction = ' или ' }, P26 = { datatype = 'wikibase-item', }, P27 = { preset = 'country', }, P31 = { datatype = 'wikibase-item', references = false, }, P37 = { datatype = 'wikibase-item', }, P39 = { datatype = 'wikibase-item', ['claim-module'] = 'Wikidata/positions', ['claim-function'] = 'formatPositionClaim', separator = '', conjunction = '', allowTables = true, }, P40 = { datatype = 'wikibase-item', }, P41 = { datatype = 'commonsMedia', size = '150x200px', }, P53 = { datatype = 'wikibase-item', category = 'P910', }, P54 = { category = 'P6112', }, P57 = { datatype = 'wikibase-item', preset = 'list', }, P58 = { datatype = 'wikibase-item', preset = 'list', }, P59 = { datatype = 'wikibase-item', category = 'P910', references = false, }, P69 = { datatype = 'wikibase-item', preset = 'list', category = 'P3876', qualifier = 'P582', }, P94 = { datatype = 'commonsMedia', size = '100x200px', }, P86 = { datatype = 'wikibase-item', preset = 'list', }, P101 = { datatype = 'wikibase-item', }, P102 = { datatype = 'wikibase-item', preset = 'list', qualifier = 'P582', category = 'P6365', }, P103 = { datatype = 'wikibase-item', }, P106 = { datatype = 'wikibase-item', ['claim-module'] = 'Wikidata/item', ['claim-function'] = 'formatEntityWithGenderClaim', conjunction = ',&#32;', }, P108 = { datatype = 'wikibase-item', preset = 'list', category = 'P4195', }, P109 = { datatype = 'commonsMedia', size = '150x150px', alt = 'Изображение автографа', }, P117 = { datatype = 'commonsMedia', size = '290x300px', alt = 'Изображение химической структуры', }, P119 = { preset = 'place', thisLocationOnly = 'true', }, P131 = { datatype = 'wikibase-item', }, P140 = { datatype = 'wikibase-item', }, P154 = { size = '220x80px', alt = 'Изображение логотипа', }, P159 = { preset = 'place', }, P161 = { preset = 'list', }, P162 = { preset = 'list', }, P163 = { datatype = 'wikibase-item', }, P166 = { datatype = 'wikibase-item', ['property-module'] = 'Wikidata/Medals', ['property-function'] = 'formatProperty', ['value-module'] = 'Wikidata/Medals', ['value-function'] = 'formatValue', before = '<div style="text-align:justify">', after = '</div>', separator = '&#32;', conjunction = '&#32;', references = false, allowTables = true, }, P190 = { datatype = 'wikibase-item', }, P212 = { preset = 'link', }, P225 = { preset = 'list', ['claim-module'] = 'Wikidata/Biology', ['claim-function'] = 'formatTaxonNameClaim', }, P237 = { datatype = 'wikibase-item', }, P241 = { datatype = 'wikibase-item', }, P242 = { datatype = 'commonsMedia', size = '300x300px', }, P247 = { formatter = 'https://nssdc.gsfc.nasa.gov/nmc/spacecraft/display.action?id=$1', }, P267 = { preset = 'link', }, P276 = { preset = 'place', }, P281 = { datatype = 'string', }, P286 = { preset = 'list', }, P296 = { formatter = 'http://osm.sbin.ru/esr/esr:$1', }, P301 = { rawArticle = true, }, P344 = { preset = 'list', }, P345 = { preset = 'link', }, P348 = { preset = 'list', ['property-module'] = 'Wikidata/Software', ['property-function'] = 'formatVersionProperty', }, P361 = { datatype = 'wikibase-item', }, P373 = { datatype = 'string', ['value-module'] = 'Wikidata/media', ['value-function'] = 'formatCommonsCategory', limit = 1, }, P374 = { datatype = 'external-id', }, P395 = { datatype = 'string', }, P407 = { datatype = 'wikibase-item', }, P410 = { datatype = 'wikibase-item', }, P412 = { datatype = 'wikibase-item', category = 'P910', }, P413 = { datatype = 'wikibase-item', ['claim-module'] = 'Wikidata/item', ['claim-function'] = 'formatEntityWithGenderClaim', conjunction = ',&#32;', category = 'P910', }, P414 = { ['claim-module'] = 'Wikidata/item', ['claim-function'] = 'applyDefaultTemplate', }, P421 = { datatype = 'wikibase-item', }, P473 = { datatype = 'string', }, P495 = { preset = 'country', }, P505 = { preset = 'list', }, P512 = { datatype = 'wikibase-item', ['property-module'] = 'Wikidata/P512', ['property-function'] = 'formatAcademicDegree', }, P527 = { preset = 'list', }, P528 = { references = false, qualifier = 'P972', }, P551 = { preset = 'place', }, P569 = { datatype = 'time', ['claim-module'] = 'Wikidata/date', ['claim-function'] = 'formatDateOfBirthClaim', }, P570 = { datatype = 'time', ['claim-module'] = 'Wikidata/date', ['claim-function'] = 'formatDateOfDeathClaim', }, P571 = { datatype = 'time', }, P576 = { datatype = 'time', }, P598 = { datatype = 'wikibase-item', }, P607 = { datatype = 'wikibase-item', preset = 'list', }, P625 = { datatype = 'globe-coordinate', }, P669 = { qualifier = 'P670', }, P685 = { formatter = 'https://www.ncbi.nlm.nih.gov/Taxonomy/Browser/wwwtax.cgi?mode=Info&id=$1', }, P721 = { preset = 'link', }, P764 = { preset = 'link', }, P803 = { datatype = 'wikibase-item', }, P856 = { datatype = 'url', }, P881 = { novalue = 'нет', category = 'P910', }, P884 = { preset = 'link', }, P915 = { category = 'P1740', }, P957 = { preset = 'link', }, P972 = { preset = 'catonly', }, P1077 = { preset = 'link', }, P1082 = { preset = 'quantity (date)', unit = 'чел.', ['property-module'] = 'Wikidata/number', ['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator' }, P1098 = { preset = 'quantity (date)', unit = 'чел.', }, P1120 = { preset = 'quantity (date)', unit = 'чел.', ['property-module'] = 'Wikidata/number', ['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator' }, P1128 = { datatype = 'quantity', preset = 'quantity (date)', unit = 'чел.', ['property-module'] = 'Wikidata/number', ['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator' }, P1114 = { datatype = 'quantity', qualifier = 'P585', }, P1174 = { preset = 'quantity (date)', unit = 'чел.', }, P1195 = { ['value-module'] = 'Wikidata/Software', ['value-function'] = 'formatExtension', conjunction = ' или ', }, P1215 = { datatype = 'quantity', ['property-module'] = 'Wikidata/number', ['property-function'] = 'formatVisualMagnitude' }, P1246 = { preset = 'link', }, P1249 = { datatype = 'time', }, P1352 = { preset = 'quantity (date)', }, P1376 = { datatype = 'wikibase-item', }, P1402 = { preset = 'link', }, P1448 = { preset = 'name', }, P1458 = { datatype = 'quantity', ['property-module'] = 'Wikidata/number', ['property-function'] = 'formatColorIndex' }, P1464 = { datatype = 'wikibase-item', }, P1476 = { preset = 'name', }, P1477 = { preset = 'name', }, P1532 = { preset = 'country', rank = '[rank:normal, rank:preferred]', }, P1543 = { datatype = 'commonsMedia', }, P1559 = { preset = 'name', }, P1603 = { preset = 'quantity (date)', unit = 'чел.', ['property-module'] = 'Wikidata/number', ['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator' }, P1621 = { size = '300x300px', }, P1692 = { preset = 'link', }, P1705 = { preset = 'name', }, P1753 = { rowArticle = true, }, P1809 = { preset = 'list', }, P1846 = { datatype = 'commonsMedia', fixdouble = true, }, P2031 = { preset = 'from-to', to = 'P2032', within = 'P570', }, P2043 = { preset = 'quantity (date)', }, P2044 = { datatype = 'quantity', }, P2046 = { preset = 'quantity (date)', siConversion = false, }, P2047 = { siConversion = false, }, P2048 = { conjunction = '&#32;или&#32;', }, P2060 = { siConversion = false, }, P2097 = { siConversion = false, }, P2120 = { siConversion = false, }, P2137 = { preset = 'quantity (date)', ['property-module'] = 'Wikidata/number', ['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator', countByThousands = true, }, P2139 = { preset = 'quantity (date)', ['property-module'] = 'Wikidata/number', ['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator', countByThousands = true, }, P2146 = { siConversion = false, }, P2214 = { siConversion = false }, P2226 = { preset = 'quantity (date)', ['property-module'] = 'Wikidata/number', ['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator', countByThousands = true, }, P2257 = { siConversion = false }, P2260 = { siConversion = false }, P2295 = { preset = 'quantity (date)', ['property-module'] = 'Wikidata/number', ['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator', countByThousands = true, }, P2324 = { datatype = 'quantity', preset = 'quantity (date)', unit = 'чел.' }, P2403 = { preset = 'quantity (date)', ['property-module'] = 'Wikidata/number', ['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator', countByThousands = true, }, P2425 = { alt = 'Изображение орденской планки', }, P2583 = { siConversion = false, }, P2597 = { preset = 'catonly', }, P2650 = { datatype = 'wikibase-item', }, P2789 = { preset = 'list', }, P2896 = { siConversion = false, }, P2910 = { size = '100x80px', }, P3083 = { formatter = 'http://simbad.u-strasbg.fr/simbad/sim-id?Ident=$1', }, P3086 = { siConversion = false, }, P3362 = { preset = 'quantity (date)', ['property-module'] = 'Wikidata/number', ['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator', countByThousands = true, }, P4614 = { category = 'P1200', }, P5348 = { siConversion = false, }, P6257 = { ['value-module'] = 'Wikidata/number', ['value-function'] = 'formatRA', }, P6258 = { ['value-module'] = 'Wikidata/number', ['value-function'] = 'formatDMS', }, P6259 = { ['references'] = false, }, P7584 = { siConversion = false, }, P8010 = { datatype = 'quantity', preset = 'quantity (date)', unit = 'чел.', ['property-module'] = 'Wikidata/number', ['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator' }, P8224 = { alt = 'Изображение молекулярной модели', }, }, categories = { ['links-to-entities-with-missing-label'] = 'Википедия:Статьи со ссылками на элементы Викиданных без подписи', ['links-to-entities-with-wikibase-error'] = 'Википедия:Страницы с ошибками скриптов, использующих Викиданные', ['links-to-entities-with-missing-local-language-label'] = 'Википедия:Статьи со ссылками на элементы Викиданных без русской подписи', ['media-contains-local-caption'] = 'Википедия:Локальная подпись у изображения из Викиданных', ['media-contains-markup'] = 'Википедия:Статьи с вики-разметкой в изображении карточки', ['media-contains-local-double'] = 'Википедия:Изображение в статье дублирует изображение в карточке', ['value-contains-table'] = 'Википедия:Статьи с табличной вставкой в карточке', }, errors = { ['property-param-not-provided'] = 'Не дан параметр свойства', ['entity-not-found'] = 'Сущность не найдена.', ['unknown-claim-type'] = 'Неизвестный тип заявления.', ['unknown-snak-type'] = 'Неизвестный тип снэка.', ['unknown-datavalue-type'] = 'Неизвестный тип значения данных.', ['unknown-entity-type'] = 'Неизвестный тип сущности.', ['unknown-property-module'] = 'Вы должны установить и property-module, и property-function.', ['unknown-claim-module'] = 'Вы должны установить и claim-module, и claim-function.', ['unknown-value-module'] = 'Вы должны установить и value-module, и value-function.', ['property-module-not-found'] = 'Модуль для отображения свойства не найден', ['property-function-not-found'] = 'Функция для отображения свойства не найдена', ['claim-module-not-found'] = 'Модуль для отображения утверждения не найден.', ['claim-function-not-found'] = 'Функция для отображения утверждения не найдена.', ['value-module-not-found'] = 'Модуль для отображения значения не найден.', ['value-function-not-found'] = 'Функция для отображения значения не найдена.', }, i18n = { somevalue = "''неизвестно''", novalue = '', -- Обстоятельства источника Q5727902 = 'около ', Q18122778 = '<span style="border-bottom: 1px dotted; cursor: help;" title="предположительно">предп.</span> ', Q30230067 = 'возможно ', Q52834024 = '<span style="border-bottom: 1px dotted; cursor: help;" title="менее чем">&lt;</span> ', Q54418095 = '<span style="border-bottom: 1px dotted; cursor: help;" title="более чем">&gt;</span> ', thousandPowers = {'', ' тыс.', ' млн', ' млрд', ' трлн'}, }, deprecatedSources = { Q355 = true, -- Facebook Q36578 = true, -- Gemeinsame Normdatei Q63056 = true, -- Find a Grave Q212256 = true, -- АиФ Q504063 = true, -- Discogs Q523660 = true, -- International Music Score Library Project by https://ru.wikipedia.org/?diff=107090748 Q1798125 = true, -- LIBRIS Q2621214 = true, -- Geni Q15222191 = true, -- BNF Q15241312 = true, -- Freebase Q19938912 = true, -- BNF Q21697707 = true, -- Хайазг Q25328680 = true, -- Prabook Q29861311 = true, -- SNAC Q86999151 = true, -- WeChangEd }, }; b786cd0414ef1bee304179c30b5daff1eda5baf8 Модуль:Transclude 828 144 331 330 2024-08-10T15:21:04Z DuOfOrl 5 1 версия импортирована Scribunto text/plain local p={} -- Вызывает внутренний шаблон с аргументами объемлющего шаблона function p.call(frame) local template = frame.args[1] local args = frame:getParent().args return frame:expandTemplate{ title=template, args=args } end -- Общая реализация для forall и call local function forallImpl(args, separator, conjunction, func) -- нумерованные ключи из args local keys = {} -- перебор в произвольном порядке, даже для нумерованных ключей for key, value in pairs(args) do if type(key) == 'number' and value and value ~= '' then table.insert(keys, key) end end table.sort(keys) local results = {} for _, key in ipairs(keys) do local value = func(args[key]) table.insert(results, value) end return mw.text.listToText(results, separator, conjunction) end -- Вызывает внутренний шаблон, передавая ему нумерованные параметры объемлющего шаблона по-одному function p.forall(frame) local template = frame.args[1] local separator = frame.args.separator or '' local conjunction = frame.args.conjunction or separator local args = frame:getParent().args local func = function(value) return frame:expandTemplate{ title = template, args = {value} } -- или другой frame? end return forallImpl(args, separator, conjunction, func) end -- Берёт нумерованные аргументы объемлющего шаблона и склеивает их в единую строку function p.join(frame) local separator = frame.args[1] or '' local conjunction = frame.args[2] or separator local args = frame:getParent().args local func = function(value) return value end return forallImpl(args, separator, conjunction, func) end -- Служебная функция: удаляет дубликаты из отсортированного массива с нумерованными индексами local function deleteDuplicates(args) local res = {} for key, value in pairs(args) do if args[key+1] ~= value then table.insert(res, value) end end return res end -- Вызывает внутренний шаблон несколько раз, передавая в него блоки аргументов объемлющего шаблона function p.npc(frame) local args = frame:getParent().args local templateFrame = frame:getParent() local template = frame.args[1] -- определение, блоки аргументов с какими номерами нужны: -- если в объемлющем шаблоне есть "параметр12" и в вызове модуля есть "параметр", то вызывается 12-й блок local nums = {} for key, _ in pairs(args) do local main, num = string.match(key, '^(.-)%s*(%d*)$') num = tonumber(num) -- учитывать "параметр12", только если задано "параметр" if num and frame.args[main] then table.insert(nums, num) end end table.sort(nums) nums = deleteDuplicates(nums) -- проходить по нужным номерам блоков по возрастанию и однократно -- подставлять в шаблон: -- 1. общие аргументы данного модуля -- 2. аргументы объемлющего шаблона вида "параметр12" как "параметр" в 12-й блок local results = {} for _, blockNum in ipairs(nums) do -- общие аргументы модуля, которые передаются в каждый блок local blockArgs = mw.clone(frame.args) -- metatable ломает expandTemplate setmetatable(blockArgs, nil) for key, value in pairs(args) do local main, num = string.match(key, '^(.-)%s*(%d*)$') num = tonumber(num) -- передавать "параметр12" как "параметр" в 12-й блок, только если есть "параметр" в вызове модуля if blockNum == num and frame.args[main] then blockArgs[main] = value end end local blockText = templateFrame:expandTemplate{ title=template; args=blockArgs } table.insert(results, blockText) end return table.concat(results) end -- Действует аналогично forall по числовой переменной, изменяющейся (по умолчанию, от 1) до f.args[2]. function p.cycle(f) local tf,ac,op=f:getParent(), {}, f.args.output or 'inline'; local sep=''; if op == 'newline' then sep='\n'; end for p,k in pairs(f.args) do if type(p)=='number' then if p>2 then ac[p-1]=k end else ac[p]=k end end local s,fh = f.args[2]:match('^%s*(%-?%d+)%s*%.%.') or 1, f.args[2]:match('%.%.%s*(%S.*)%s*$') or f.args[2] or ''; fh=tonumber(fh) or fh:match('^%s*(.-)%s*$'); s=tonumber(s); local acr={}; if not s then error('Начало цикла «'..s..'» — не число') end local function dc(order) local r=tf:expandTemplate{ title=f.args[1]; args={s,unpack(ac)} } if order == 'desc' then s=s-1; else s=s+1; end if r~='' then table.insert(acr,r); return r end end if type(fh)=='number' then if fh > s then while s<=fh do dc('asc') end else while s>=fh do dc('desc') end end elseif fh~='' then while tf:expandTemplate{ title=fh; args={s,unpack(ac)} } do dc('asc') end else while dc('asc') do end end return table.concat(acr, sep) end return p c17cfab4cebc23157f5ab8d18c7e4f5c273bfa59 Шаблон:Replace 10 145 333 332 2024-08-10T15:21:04Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{safesubst:<noinclude />#invoke:String|replace|source={{{1}}}|{{{2}}}|{{{3}}}|plain={{{plain|true}}}|count={{{count|}}}}}<noinclude> {{doc}} </noinclude> 7752c3c70ae8c46a89a0808aa282956866dbba5b Шаблон:Str left 10 146 335 334 2024-08-10T15:21:04Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{<includeonly>safesubst:</includeonly>padleft:|{{{2|1}}}|{{{1|}}}}}<noinclude> {{doc}} </noinclude> c1f57b63826f4d455dcaec8d2c24a2b8268f42ec Шаблон:Nobr 10 147 337 336 2024-08-10T15:21:05Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <includeonly><span class="nowrap">{{{1}}}</span></includeonly><noinclude> {{doc}} <!-- Пожалуйста, добавляйте категории и интервики на страницу документации! --> </noinclude> 989c6f164ed3a8543e916c8f1746ba1ab94fb068 Шаблон:If-wikidata 10 148 339 338 2024-08-10T15:21:05Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{#switch:{{wikidata|{{{1|}}}|{{{2|}}}|plain={{{plain|true}}}|from={{{from|}}}|somevalue={{{somevalue|}}}|novalue={{{novalue|}}}}}|значение отсутствует|={{{4|}}}|#default={{{3}}}}}<noinclude> {{doc}} </noinclude> a8a37fd2c4f1a266ec48783d7d0ad22cdcd812cb Модуль:Wikidata/media 828 149 341 340 2024-08-10T15:21:06Z DuOfOrl 5 1 версия импортирована Scribunto text/plain local p = {} -- Константы local contentLanguageCode = mw.getContentLanguage():getCode(); function p.formatCommonsCategory( context, options, value ) local link = 'commons:Category:' .. value local title = value .. ' на Викискладе' if ( options['text'] and options['text'] ~= '' ) then title = options['text'] end commons = '[[' .. link .. '|' .. title .. ']]' --Commons icon if ( not options['icon'] or options['icon'] ~= '-' ) then local icon_size = '15px' if ( options['icon_size'] and options['icon_size'] ~= '' ) then icon_size = options['icon_size'] end commons = '[[File:Commons-logo.svg|' .. icon_size .. '|link=' .. link .. '|alt=Логотип Викисклада]] ' .. commons end --Text before and after link if ( options['text_before'] and options['text_before'] ~= '' ) then if ( options['text_before'] ~= '-' ) then commons = options['text_before'] .. ' ' .. commons end end if ( options['text_after'] and options['text_after'] ~= '' ) then if ( options['text_after'] ~= '-' ) then commons = commons .. ' ' .. options['text_after'] end end return commons end --[[ Временный хак, нужно добавить config, getConfig и getCategoryByCode в options, чтобы они были доступны в любом месте кода. ]] local config; local function getCategoryByCode( code, sortkey ) if config == nil then config = require( 'Module:Wikidata/config' ); end; local value = config[ 'categories' ][ code ]; if not value or value == '' then return ''; end return '[[Category:' .. value .. ']]'; end local function getCaption( context, options ) local caption = '' if options.qualifiers and options.qualifiers.P2096 then for i, qualifier in pairs( options.qualifiers.P2096 ) do if ( qualifier and qualifier.datavalue and qualifier.datavalue.type == 'monolingualtext' and qualifier.datavalue.value and qualifier.datavalue.value.language == contentLanguageCode ) then caption = qualifier.datavalue.value.text break end end end if options['appendTimestamp'] and options.qualifiers and options.qualifiers.P585 and options.qualifiers.P585[1] then local moment = context.formatValueDefault( context, options, options.qualifiers.P585[1].datavalue ) if not caption or caption == '' then caption = moment else caption = caption .. ', ' .. moment end end local localValue = ''; if options[ 'value' ] and options[ 'value' ] ~= '' then localValue = options[ 'value' ]; end local localCaption = ''; if options[ 'caption' ] and options[ 'caption' ] ~= '' then localCaption = options[ 'caption' ]; end if localValue ~= '' then caption = localCaption; end local formattedCaption = '' if caption ~= '' then formattedCaption = context.wrapQualifier( caption, 'P2096', { class = 'media-caption', style = 'display:block' } ); end if localValue == '' and localCaption ~= '' then formattedCaption = formattedCaption .. getCategoryByCode( 'media-contains-local-caption' ) if options.frame:preprocess('{{REVISIONID}}') == '' then formattedCaption = formattedCaption .. '<span class="error" style="font-size:94%;">Локальная подпись не используется, потому что изображение берётся из Викиданных, см. [[Википедия:Шаблоны-карточки#Описание изображения в Викиданных|здесь]]</span>' end end return caption, formattedCaption end function p.formatCommonsMediaValue( context, options, value ) local image = value; local caption, formattedCaption = getCaption( context, options ) if not string.find( value, '[%[%]%{%}]' ) and not string.find( value, 'UNIQ%-%-imagemap' ) then -- если в value не содержится викикод или imagemap, то викифицируем имя файла -- ищем слово imagemap в строке, потому что вставляется плейсхолдер: [[PHAB:T28213]] image = '[[File:' .. value .. '|frameless'; if options[ 'border' ] and options[ 'border' ] ~= '' then image = image .. '|border'; end local size = options[ 'size' ]; if size and size ~= '' then if not string.match( size, 'px$' ) and not string.match( size, 'пкс$' ) -- TODO: использовать перевод для языка вики then size = size .. 'px' end -- временно if string.match( size, 'pxpx' ) then image = '[[Категория:Википедия:Изображение с pxpx в размере]]' .. image end else size = fileDefaultSize; end image = image .. '|' .. size; if options[ 'alt' ] and options[ 'alt' ] ~= '' then image = image .. '|alt=' .. options[ 'alt' ]; end if caption ~= '' then image = image .. '|' .. caption end image = image .. ']]'; if formattedCaption ~= '' then image = image .. '<br>' .. formattedCaption; end else image = image .. formattedCaption .. getCategoryByCode( 'media-contains-markup' ); end if options.entity and options.fixdouble then local page = mw.title.getCurrentTitle() local txt = page:getContent() if txt and txt:match(':' .. value) and mw.title.getCurrentTitle():inNamespace(0) then if options.frame:preprocess('{{REVISIONID}}') == '' then image = image .. '<span class="error">Это изображение встречается ниже по тексту статьи; пожалуйста, уберите одну из копий (не потеряв при этом подпись)</span>' end image = image .. getCategoryByCode( 'media-contains-local-double' ) end end return image end return p ec384e72491465f4103cce95a8f9467df428a432 Шаблон:Join 10 150 343 342 2024-08-10T15:21:06Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{<includeonly>safesubst:</includeonly>#invoke:Separated entries|main|separator={{{separator|}}}}}<noinclude> {{doc}} <!-- Категории — на подстраницу /doc, интервики — в Викиданные. --> </noinclude> 92bb17b5322d3ae0ceab93d4dad3d31810d47eb0 Модуль:Color contrast 828 151 345 344 2024-08-10T15:21:07Z DuOfOrl 5 1 версия импортирована Scribunto text/plain -- -- This module implements -- {{Color contrast ratio}} -- {{Greater color contrast ratio}} -- {{ColorToLum}} -- {{RGBColorToLum}} -- local p = {} local HTMLcolor = mw.loadData( 'Module:Color contrast/colors' ) local function sRGB ( v ) if (v <= 0.03928) then v = v / 12.92 else v = math.pow((v+0.055)/1.055, 2.4) end return v end local function rgbdec2lum( R, G, B ) if ( 0 <= R and R < 256 and 0 <= G and G < 256 and 0 <= B and B < 256 ) then return 0.2126 * sRGB(R/255) + 0.7152 * sRGB(G/255) + 0.0722 * sRGB(B/255) else return '' end end local function hsl2lum( h, s, l ) if ( 0 <= h and h < 360 and 0 <= s and s <= 1 and 0 <= l and l <= 1 ) then local c = (1 - math.abs(2*l - 1))*s local x = c*(1 - math.abs( math.fmod(h/60, 2) - 1) ) local m = l - c/2 local r, g, b = m, m, m if( 0 <= h and h < 60 ) then r = r + c g = g + x elseif( 60 <= h and h < 120 ) then r = r + x g = g + c elseif( 120 <= h and h < 180 ) then g = g + c b = b + x elseif( 180 <= h and h < 240 ) then g = g + x b = b + c elseif( 240 <= h and h < 300 ) then r = r + x b = b + c elseif( 300 <= h and h < 360 ) then r = r + c b = b + x end return rgbdec2lum(255*r, 255*g, 255*b) else return '' end end local function color2lum( c ) if (c == nil) then return '' end -- whitespace c = c:match( '^%s*(.-)[%s;]*$' ) -- lowercase c = c:lower() -- first try to look it up local L = HTMLcolor[c] if (L ~= nil) then return L end -- convert from hsl if mw.ustring.match(c,'^hsl%([%s]*[0-9][0-9%.]*[%s]*,[%s]*[0-9][0-9%.]*%%[%s]*,[%s]*[0-9][0-9%.]*%%[%s]*%)$') then local h, s, l = mw.ustring.match(c,'^hsl%([%s]*([0-9][0-9%.]*)[%s]*,[%s]*([0-9][0-9%.]*)%%[%s]*,[%s]*([0-9][0-9%.]*)%%[%s]*%)$') return hsl2lum(tonumber(h), tonumber(s)/100, tonumber(l)/100) end -- convert from rgb if mw.ustring.match(c,'^rgb%([%s]*[0-9][0-9]*[%s]*,[%s]*[0-9][0-9]*[%s]*,[%s]*[0-9][0-9]*[%s]*%)$') then local R, G, B = mw.ustring.match(c,'^rgb%([%s]*([0-9][0-9]*)[%s]*,[%s]*([0-9][0-9]*)[%s]*,[%s]*([0-9][0-9]*)[%s]*%)$') return rgbdec2lum(tonumber(R), tonumber(G), tonumber(B)) end -- convert from rgb percent if mw.ustring.match(c,'^rgb%([%s]*[0-9][0-9%.]*%%[%s]*,[%s]*[0-9][0-9%.]*%%[%s]*,[%s]*[0-9][0-9%.]*%%[%s]*%)$') then local R, G, B = mw.ustring.match(c,'^rgb%([%s]*([0-9][0-9%.]*)%%[%s]*,[%s]*([0-9][0-9%.]*)%%[%s]*,[%s]*([0-9][0-9%.]*)%%[%s]*%)$') return rgbdec2lum(255*tonumber(R)/100, 255*tonumber(G)/100, 255*tonumber(B)/100) end -- remove leading # (if there is one) and whitespace c = mw.ustring.match(c, '^[%s#]*([a-f0-9]*)[%s]*$') -- split into rgb local cs = mw.text.split(c or '', '') if( #cs == 6 ) then local R = 16*tonumber('0x' .. cs[1]) + tonumber('0x' .. cs[2]) local G = 16*tonumber('0x' .. cs[3]) + tonumber('0x' .. cs[4]) local B = 16*tonumber('0x' .. cs[5]) + tonumber('0x' .. cs[6]) return rgbdec2lum(R, G, B) elseif ( #cs == 3 ) then local R = 16*tonumber('0x' .. cs[1]) + tonumber('0x' .. cs[1]) local G = 16*tonumber('0x' .. cs[2]) + tonumber('0x' .. cs[2]) local B = 16*tonumber('0x' .. cs[3]) + tonumber('0x' .. cs[3]) return rgbdec2lum(R, G, B) end -- failure, return blank return '' end function p._greatercontrast(args) local bias = tonumber(args['bias'] or '0') or 0 local v1 = color2lum(args[1] or '') local c2 = args[2] or '#FFFFFF' local v2 = color2lum(c2) local c3 = args[3] or '#000000' local v3 = color2lum(c3) local ratio1 = 0; local ratio2 = 0; if (type(v1) == 'number' and type(v2) == 'number') then ratio1 = (v2 + 0.05)/(v1 + 0.05) ratio1 = (ratio1 < 1) and 1/ratio1 or ratio1 end if (type(v1) == 'number' and type(v3) == 'number') then ratio2 = (v3 + 0.05)/(v1 + 0.05) ratio2 = (ratio2 < 1) and 1/ratio2 or ratio2 end return (ratio1 + bias > ratio2) and c2 or c3 end function p._ratio(args) local v1 = color2lum(mw.text.unstripNoWiki(args[1] or '')) local v2 = color2lum(mw.text.unstripNoWiki(args[2] or '')) if (type(v1) == 'number' and type(v2) == 'number') then -- v1 should be the brighter of the two. if v2 > v1 then v1, v2 = v2, v1 end return (v1 + 0.05)/(v2 + 0.05) else return args['error'] or '?' end end function p._styleratio(args) local style = (args[1] or ''):lower() local bg, fg = 'white', '#202122' local lum_bg, lum_fg = 1, 0.016 if args[2] then local lum = color2lum(args[2]) if lum ~= '' then bg, lum_bg = args[2], lum end end if args[3] then local lum = color2lum(args[3]) if lum ~= '' then fg, lum_fg = args[3], lum end end local slist = mw.text.split(style or '', ';') for k = 1, #slist do local s = slist[k] local k, v = s:match( '^[%s]*([^:]-):([^:]-)[%s;]*$' ) k = k or '' v = v or '' if (k:match('^[%s]*(background)[%s]*$') or k:match('^[%s]*(background%-color)[%s]*$')) then local lum = color2lum(v) if( lum ~= '' ) then bg, lum_bg = v, lum end elseif (k:match('^[%s]*(color)[%s]*$')) then local lum = color2lum(v) if( lum ~= '' ) then bg, lum_fg = v, lum end end end if lum_bg > lum_fg then return (lum_bg + 0.05)/(lum_fg + 0.05) else return (lum_fg + 0.05)/(lum_bg + 0.05) end end function p.lum(frame) return color2lum(frame.args[1] or frame:getParent().args[1]) end function p.ratio(frame) local args = frame.args[1] and frame.args or frame:getParent().args return p._ratio(args) end function p.styleratio(frame) local args = frame.args[1] and frame.args or frame:getParent().args return p._styleratio(args) end function p.greatercontrast(frame) local args = frame.args[1] and frame.args or frame:getParent().args return p._greatercontrast(args) end return p cce580326bee8eaf3c81df6c76c04a9a2909dfa2 Модуль:Color contrast/colors 828 152 347 346 2024-08-10T15:21:07Z DuOfOrl 5 1 версия импортирована Scribunto text/plain return { aliceblue = 0.92880068253475, antiquewhite = 0.84646951707754, aqua = 0.7874, aquamarine = 0.8078549208338, azure = 0.97265264954166, beige = 0.8988459998705, bisque = 0.80732327372979, black = 0, blanchedalmond = 0.85084439608156, blue = 0.0722, blueviolet = 0.12622014321946, brown = 0.098224287876511, burlywood = 0.51559844533893, cadetblue = 0.29424681085422, chartreuse = 0.76032025902623, chocolate = 0.23898526114557, coral = 0.37017930872924, cornflowerblue = 0.30318641994179, cornsilk = 0.93562110372965, crimson = 0.16042199953026, cyan = 0.7874, darkblue = 0.018640801980939, darkcyan = 0.20329317839046, darkgoldenrod = 0.27264703559993, darkgray = 0.39675523072563, darkgreen = 0.091143429047575, darkgrey = 0.39675523072563, darkkhaki = 0.45747326349994, darkmagenta = 0.07353047651207, darkolivegreen = 0.12651920884889, darkorange = 0.40016167026524, darkorchid = 0.13413142174857, darkred = 0.054889674531132, darksalmon = 0.40541471563381, darkseagreen = 0.43789249325969, darkslateblue = 0.065792846227988, darkslategray = 0.067608151928044, darkslategrey = 0.067608151928044, darkturquoise = 0.4874606277449, darkviolet = 0.10999048339343, deeppink = 0.23866895828276, deepskyblue = 0.44481603395575, dimgray = 0.14126329114027, dimgrey = 0.14126329114027, dodgerblue = 0.27442536991456, firebrick = 0.10724525535015, floralwhite = 0.95922484825004, forestgreen = 0.18920812076002, fuchsia = 0.2848, gainsboro = 0.71569350050648, ghostwhite = 0.94311261886323, gold = 0.69860877428159, goldenrod = 0.41919977809569, gray = 0.2158605001139, green = 0.15438342968146, greenyellow = 0.80609472611453, grey = 0.2158605001139, honeydew = 0.96336535554782, hotpink = 0.34658438169715, indianred = 0.21406134963884, indigo = 0.03107561486337, ivory = 0.99071270600615, khaki = 0.77012343394121, lavender = 0.80318750514521, lavenderblush = 0.90172748631046, lawngreen = 0.73905893124963, lemonchiffon = 0.94038992245622, lightblue = 0.63709141280807, lightcoral = 0.35522120733135, lightcyan = 0.94587293494829, lightgoldenrodyellow = 0.93348351018297, lightgray = 0.65140563741982, lightgreen = 0.69091979956865, lightgrey = 0.65140563741982, lightpink = 0.58566152734898, lightsalmon = 0.4780675225206, lightseagreen = 0.35050145117042, lightskyblue = 0.56195637618331, lightslategray = 0.23830165007287, lightslategrey = 0.23830165007287, lightsteelblue = 0.53983888284666, lightyellow = 0.98161818392882, lime = 0.7152, limegreen = 0.44571042246098, linen = 0.88357340984379, magenta = 0.2848, maroon = 0.045891942324215, mediumaquamarine = 0.49389703310801, mediumblue = 0.044077780212328, mediumorchid = 0.21639251153773, mediumpurple = 0.22905858091648, mediumseagreen = 0.34393112338131, mediumslateblue = 0.20284629471622, mediumspringgreen = 0.70704308194184, mediumturquoise = 0.5133827926448, mediumvioletred = 0.14371899849357, midnightblue = 0.02071786635086, mintcream = 0.97834604947588, mistyrose = 0.82183047859185, moccasin = 0.80083000991567, navajowhite = 0.76519682342785, navy = 0.015585128108224, oldlace = 0.91900633405549, olive = 0.20027537200568, olivedrab = 0.22593150951929, orange = 0.4817026703631, orangered = 0.25516243753416, orchid = 0.31348806761439, palegoldenrod = 0.78792647887614, palegreen = 0.77936759006353, paleturquoise = 0.76436077921714, palevioletred = 0.28754994117889, papayawhip = 0.87797100199835, peachpuff = 0.74905589878251, peru = 0.30113074877936, pink = 0.63271070702466, plum = 0.45734221587969, powderblue = 0.68254586500605, purple = 0.061477070432439, rebeccapurple = 0.07492341159447, red = 0.2126, rosybrown = 0.32319457649407, royalblue = 0.16663210743188, saddlebrown = 0.097922285020521, salmon = 0.36977241527596, sandybrown = 0.46628543696283, seagreen = 0.19734199706275, seashell = 0.92737862206922, sienna = 0.13697631337098, silver = 0.52711512570581, skyblue = 0.55291668518184, slateblue = 0.14784278062136, slategray = 0.20896704076536, slategrey = 0.20896704076536, snow = 0.96533341834849, springgreen = 0.73052306068529, steelblue = 0.20562642207625, tan = 0.48237604163921, teal = 0.16996855778968, thistle = 0.56818401093733, tomato = 0.30638612719415, turquoise = 0.5895536427578, violet = 0.40315452986676, wheat = 0.74909702820482, white = 1, whitesmoke = 0.91309865179342, yellow = 0.9278, yellowgreen = 0.50762957208707, } 6ae47fdb24de4eed5ec26d203faf5341a388987b Шаблон:Yesno-yes 10 153 349 348 2024-08-10T15:21:07Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{safesubst:<noinclude />yesno|{{{1}}}|yes={{{yes|yes}}}|no={{{no|no}}}|blank={{{blank|yes}}}|¬={{{¬|yes}}}|def={{{def|yes}}}}}<noinclude> {{doc}} </noinclude> 3792ff694708f98102e3a6d556abe73bedc29069 Шаблон:Карточка/оригинал названия 10 154 351 350 2024-08-10T15:21:08Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{wikidata|p1705[language!:ru]|{{{1|}}}|separator=<br>|conjunction=<br>|monolingualLangTemplate=lang|from={{{from|}}}}}<!-- -->{{#if:{{NAMESPACE}}||{{#if:{{{1|}}}|{{#ifeq:{{#invoke:String|find|{{{1|}}}|span}}|0|[[Категория:Википедия:Статьи с оригиналом названия без шаблона lang-XX]]}}}}}}<noinclude>{{doc}}</noinclude> 4eccda042428e1113ff320ff5d6b760a7f52b088 Шаблон:Br separated entries 10 155 353 352 2024-08-10T15:21:08Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{<includeonly>safesubst:</includeonly>#invoke:Separated entries|br}}<noinclude> {{doc}} </noinclude> 2113c3c6e95a84235b9f7a85e7ea17208e8f91df Шаблон:Карточка/блок с маркерами 10 156 355 354 2024-08-10T15:21:09Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{#invoke:Infobox/bulleted block|main}}<noinclude>{{doc}}</noinclude> 71e7755aa4fb1e445f008da13d6fa4212aea3c38 Шаблон:Карточка/блок 10 157 357 356 2024-08-10T15:21:10Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <includeonly>{{#invoke:Infobox|renderLines}}</includeonly><noinclude>{{doc}}</noinclude> b76f4bc95a8a44fea1fa0f577d84111b51ce1385 Модуль:Separated entries 828 158 359 358 2024-08-10T15:21:10Z DuOfOrl 5 1 версия импортирована Scribunto text/plain -- This module takes positional parameters as input and concatenates them with -- an optional separator. The final separator (the "conjunction") can be -- specified independently, enabling natural-language lists like -- "foo, bar, baz and qux". local compressSparseArray = require('Module:TableTools').compressSparseArray local p = {} function p._main(args) local separator = args.separator -- Decode (convert to Unicode) HTML escape sequences, such as "&#32;" for space. and mw.text.decode(args.separator) or '' local conjunction = args.conjunction and mw.text.decode(args.conjunction) or separator -- Discard named parameters. local values = compressSparseArray(args) return mw.text.listToText(values, separator, conjunction) end local function makeInvokeFunction(separator, conjunction) return function (frame) local args = require('Module:Arguments').getArgs(frame) args.separator = separator or args.separator args.conjunction = conjunction or args.conjunction return p._main(args) end end p.main = makeInvokeFunction() p.br = makeInvokeFunction('<br />') p.newline = makeInvokeFunction('\n') p.comma = makeInvokeFunction(mw.message.new('comma-separator'):plain()) return p 33a68f0a46d62c42b6523a548f0f881e82ecfe58 Модуль:Infobox/bulleted block 828 159 361 360 2024-08-10T15:21:10Z DuOfOrl 5 1 версия импортирована Scribunto text/plain local p = {} -- takes strings or nils; returns a string function makeText(frame, text, wikidata, from) if wikidata and wikidata ~= ''then return frame:expandTemplate{title='Wikidata', args={wikidata, text or '', from=from or ''}} else return text or '' end end -- from [[ru:Модуль:Infobox]] local function maxNumber ( args ) local maxNumber = 0 for argName, _ in pairs(args) do local argNumber = mw.ustring.match(argName, '^[^0-9]+([0-9]+)$') if argNumber and tonumber(argNumber) > maxNumber then maxNumber = tonumber(argNumber) end end return maxNumber end function p.main(frame) local args = frame:getParent().args local maxNumberArgs = maxNumber(args) local texts = {} for i = 1, maxNumberArgs do if args['текст' .. i] then texts[i] = makeText(frame, args['текст' .. i], args['викиданные' .. i], args['from']) end end local textsAreEmpty = true for i = 1, maxNumberArgs do if texts[i] and texts[i] ~= '' then textsAreEmpty = false end end local results = {} if not textsAreEmpty and args['подзаголовок'] and args['подзаголовок'] ~= '' then results['текст1'] = args['подзаголовок'] results['стиль_текста1'] = 'padding-bottom:0; border-bottom:0; text-align:left; font-weight:bold;' end local mainText = makeText(frame, args['текст'], args['викиданные'], args['from']) if mainText == '' and args['метка'] and args['метка'] ~= '' and not textsAreEmpty then mainText = '&nbsp;' end if mainText and mainText ~= '' then results['метка2'] = args['метка'] results['стиль_метки2'] = 'padding-bottom:0; border-bottom:0;' results['текст2'] = mainText results['стиль_текста2'] = 'padding-bottom:0; border-bottom:0;' end for i = 1, maxNumberArgs do if texts[i] and texts[i] ~= '' then results['метка' .. (i+2)] = '&nbsp;•&nbsp;' .. (args['метка' .. i] or '') results['текст' .. (i+2)] = texts[i] local last = true for j = i+1, maxNumberArgs do if texts[j] and texts[j] ~= '' then last = false end end if last then results['стиль_метки' .. (i+2)] = 'font-weight:normal; padding-top:0; border-top:0;' results['стиль_текста' .. (i+2)] = 'padding-top:0; border-top:0;' else results['стиль_метки' .. (i+2)] = 'font-weight:normal; padding-bottom:0; border-bottom:0; padding-top:0; border-top:0;' results['стиль_текста' .. (i+2)] = 'padding-bottom:0; border-bottom:0; padding-top:0; border-top:0;' end end end return frame:expandTemplate{title='Карточка/блок', args=results} end return p 856b97606e1f2809c940e384f6fe71a575ca019e Шаблон:Число 10 160 363 362 2024-08-10T15:21:11Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{formatnum: {{replace|{{{1}}}|,|.}} }}{{#if: {{{1|}}} | {{#if: {{{2|}}} | {{nobr|1=&nbsp;{{{2|}}}}} }} }}<noinclude> {{doc}} </noinclude> acfc1e9cec817e6742b18106f020ac388ececc7e Шаблон:T 10 161 365 364 2024-08-10T15:21:11Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki #перенаправление [[Шаблон:Tl]] c0a76efe437d8a513d9f6878297f399a23944abd Шаблон:Tl 10 162 367 366 2024-08-10T15:21:12Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{{{{|safesubst:}}}#invoke: Template call code | withoutParams }}<noinclude>{{doc}}</noinclude> 61fe4d068895a5e7e5802767f5d7df71a7561c57 Модуль:Wikidata/count 828 163 369 368 2024-08-10T15:21:12Z DuOfOrl 5 1 версия импортирована Scribunto text/plain local p = {} function p.getCount( context, options ) if ( not context ) then error( 'context not specified' ); end; if ( not options ) then error( 'options not specified' ); end; if ( not options.entity ) then error( 'options.entity missing' ); end; local claims; if options.property then -- TODO: Почему тут может не быть property? claims = context.selectClaims( options, options.property ); end if claims == nil then return ''; --TODO error? end return table.getn(claims); end function p.isMultiple( context, options ) local count = p.getCount( context, options ); local multiple = ''; if( count ~= nil and count ~= '' and count > 1 ) then multiple = 1; end return multiple; end return p 8ccf5dd7170a466674627b0afdf32c6bd2318154 Шаблон:Str sub 10 164 371 370 2024-08-10T15:21:13Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <includeonly>{{{{{|safesubst:}}}#invoke:String|sublength|s={{{1}}}|i={{{2|0}}}|len={{{3|0}}}}}</includeonly><noinclude> {{doc}} </noinclude> 3043790f8803e868cf6097b475fd58ba742887fe Шаблон:Без начала 10 165 373 372 2024-08-10T15:21:13Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{<includeonly>safesubst:</includeonly>#ifeq:{{<includeonly>safesubst:</includeonly>Str_left|{{{1}}}|{{<includeonly>safesubst:</includeonly>#expr:{{<includeonly>safesubst:</includeonly>str len|{{{2}}}*}}-1}}}}*|{{{2}}}*|{{<includeonly>safesubst:</includeonly>Str_right|{{{1}}}|{{<includeonly>safesubst:</includeonly>#expr:{{<includeonly>safesubst:</includeonly>str len|{{{2}}}*}}-1}}}}|{{{1}}}}}<noinclude>{{doc}}</noinclude> 9fbca6f1fc236cb17fe77d76891e3f9c2afa2117 Шаблон:Str len 10 166 375 374 2024-08-10T15:21:14Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{{{{|safesubst:}}}#invoke:String|len|s={{{1|}}}}}<noinclude> {{doc}} <!-- Add categories and interwikis to the /doc subpage, not here! --> </noinclude> 95f10258d5214440d2706952656564f216c2e4cc Шаблон:Str rightc 10 167 377 376 2024-08-10T15:21:15Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{<includeonly>safesubst:</includeonly>Str sub|{{{1}}}|{{<includeonly>safesubst:</includeonly>#expr:{{<includeonly>safesubst:</includeonly>Str len|{{{1}}}}}-{{{2}}}}}|{{{2}}}}}<noinclude>{{doc}}</noinclude> 0401d500dcc2224d44867ba0ea1f6c0fbeb758a0 Модуль:Hash 828 168 379 378 2024-08-10T15:21:15Z DuOfOrl 5 1 версия импортирована Scribunto text/plain local getArgs = require('Module:Arguments').getArgs local p = {} local function inTable(table, value) for k, v in pairs(table) do if v == value then return true end end return false end function p.list(frame) return table.concat(mw.hash.listAlgorithms(), '; ') end function p.main(frame) local args = getArgs(frame, { frameOnly = true }) local algorithm if not args[1] then return '<span class="error">Не указана строка для хеширования.</span>' end if args[2] then if not inTable(mw.hash.listAlgorithms(), args[2]) then return '<span class="error">Алгоритм хеширования ' .. args[2] .. ' не поддерживается, или вы неточно указали его имя. Используйте функцию <kbd>mw.hash.listAlgorithms()</kbd> для получения списка доступных алгоритмов.</span>' end algorithm = args[2] else -- Алгоритм выбран из соображений быстродействия (см. [[:en:Fowler–Noll–Vo hash function]]), -- 64-битная функция используется для уменьшения вероятности коллизий до пренебрежимо малой -- величины. Возможно, есть лучшая опция — проверяйте. algorithm = 'fnv164' end return mw.hash.hashValue(algorithm, args[1]) end return p 5d18513e574435f191164695449a620b031f93ec Шаблон:Карточка/официальное название 10 169 381 380 2024-08-10T15:21:15Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{wikidata|p1448[language!:ru]|{{{1|}}}|separator=<br>|conjunction=<br>|monolingualLangTemplate=lang|from={{{from|}}}}}<noinclude>{{doc}}</noinclude> 708a700c58a199343531d8fb3eec7ee897e92732 Шаблон:Карточка/флаг и герб 10 170 383 382 2024-08-10T15:21:16Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{#if:{{if-wikidata|p41|{{{флаг|}}}|1|from={{{from|}}}}}{{if-wikidata|p94|{{{герб|}}}|1|from={{{from|}}}}}|<table role="presentation" style="background:inherit; border-collapse:collapse; width:100%; display:table; text-align:center;"> <tr> {{if-wikidata|p41|{{{флаг|}}}|<td style<nowiki>=</nowiki>"vertical-align: middle">{{wikidata|p41|{{{флаг|}}}|from={{{from|}}}|border=true|size={{#if:{{{флаг ширина|}}}|{{{флаг ширина|}}}|160x160px}}|alt={{#if:{{{флаг подпись|}}} | {{{флаг подпись}}} | Флаг }} }}</td>}} {{if-wikidata|p94|{{{герб|}}}|<td style<nowiki>=</nowiki>"vertical-align: middle">{{wikidata|p94|{{{герб|}}}|from={{{from|}}}|size={{#if:{{{герб ширина|}}}|{{{герб ширина|}}}|90x160px}}|alt={{#if:{{{герб подпись|}}} | {{{герб подпись}}} | Герб }} }}</td>}} </tr> {{#if:{{if-wikidata|p41|{{{флаг|}}}|1|from={{{from|}}}}}{{if-wikidata|p94|{{{герб|}}}|1|from={{{from|}}}}}|<tr> {{if-wikidata|p41|{{{флаг|}}}|<td>{{#if:{{{флаг подпись|}}} | {{{флаг подпись}}} | Флаг }}</td>}} {{if-wikidata|p94|{{{герб|}}}|<td>{{#if:{{{герб подпись|}}} | {{{герб подпись}}} | Герб }}</td>}} </tr>}}</table> }}<noinclude>{{doc}}</noinclude> 6d024d548f061491090c2a71067f26911973a9fd Шаблон:Doc 10 171 385 384 2024-08-10T15:21:16Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <includeonly>{{doc/begin|{{SUBJECTSPACE}}:{{PAGENAME:{{{1|{{SUBJECTPAGENAME}}/doc}}}}}}} {{#if: {{{1|}}} | {{#ifexist: {{{1}}} | {{{{{1}}}|{{{2|}}}|{{{3|}}}|{{{4|}}}|{{{5|}}}}} | {{#ifexist: {{SUBJECTSPACE}}:{{{1}}} | {{{{{1}}}|{{{2|}}}|{{{3|}}}|{{{4|}}}|{{{5|}}}}} | {{Документировать|{{{1}}}}} }} }} | {{#ifexist: {{SUBJECTPAGENAME}}/doc | {{{{SUBJECTPAGENAME}}/doc}} | {{Документировать|{{SUBJECTPAGENAME}}/doc}} }} }} {{doc/end}}</includeonly><noinclude> {{doc}} </noinclude> 391c7f0f075319e6b3305557c55e98c581696c71 Шаблон:Doc/begin 10 172 387 386 2024-08-10T15:21:16Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <includeonly><templatestyles src="Шаблон:Doc/styles.css" /> <div class="ts-doc-doc" id="doc"> <div class="ts-doc-header" id="Документация"> <div class="ts-doc-heading">Документация</div> {{#if: {{{inline|}}} || {{Действия для страницы|lc={{{1}}}|nowatch=yes}} }} </div> <div class="ts-doc-content"></includeonly><noinclude> {{doc}} </noinclude> c753f0a9f65d86707cdffaf93fb49c2c52daf92b Шаблон:Doc/styles.css 10 173 389 388 2024-08-10T15:21:18Z DuOfOrl 5 1 версия импортирована sanitized-css text/css .ts-doc-doc { background-color: var(--background-color-progressive-subtle, #eaf3ff); border: 1px solid var(--border-color-content-added, #afb6e9); clear: both; margin-top: 1em; } /* Ctrl+F ":target" in [[MediaWiki:Common.css]] */ .ts-doc-doc sup.reference:target, .ts-doc-doc ol.references li:target, .ts-doc-doc .highlight-target:target, .ts-doc-doc cite:target, .ts-doc-doc span.citation:target { background: var(--ruwiki-background-color-blue200, #cfe3ff); } .ts-doc-header { align-items: center; background: var(--ruwiki-background-color-blue200, #cfe3ff); display: flex; flex-wrap: wrap; padding: .642857em 1em .5em; overflow: hidden; } .ts-doc-header .ts-tlinks-tlinks { margin-left: auto; } .ts-doc-content { padding: .214286em 1em; } .ts-doc-content:after { content: ''; clear: both; display: block; } .ts-doc-heading { display: inline-block; padding-left: 2em; background: url(//upload.wikimedia.org/wikipedia/commons/c/ca/OOjs_UI_icon_info.svg) center left no-repeat; background-size: contain; font-size: small; min-height: 1.75em; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; } @media screen { html.skin-theme-clientpref-night .ts-doc-heading { background-image: url(//upload.wikimedia.org/wikipedia/commons/c/c0/OOjs_UI_icon_info-invert.svg); } } @media screen and (prefers-color-scheme: dark) { html.skin-theme-clientpref-os .ts-doc-heading { background-image: url(//upload.wikimedia.org/wikipedia/commons/c/c0/OOjs_UI_icon_info-invert.svg); } } .ts-doc-content > *:first-child, .ts-doc-footer > *:first-child { margin-top: .5em; } .ts-doc-content > *:last-child, .ts-doc-footer > *:last-child { margin-bottom: .5em; } .ts-doc-footer { background-color: var(--background-color-progressive-subtle, #eaf3ff); border: 1px solid var(--border-color-content-added, #afb6e9); padding: .214286em 1em; margin-top: .214286em; margin-bottom: .214286em; font-style: italic; } @media (max-width: 719px) { .ts-doc-header { display: block; } .ts-doc-header .ts-tlinks-tlinks { float: none; } } /* [[Категория:Шаблоны:Подстраницы CSS]] */ be8d912472a37a6051bee114da86f913839e7ca0 Шаблон:Действия для страницы 10 174 391 390 2024-08-10T15:21:18Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <templatestyles src="Шаблон:Действия для страницы/styles.css" /><div style="{{#ifeq: {{yesno-yes|{{{right|}}}}} | yes || float:none; }}" class="ts-tlinks-tlinks mw-editsection-like plainlinks"><span class="mw-editsection-bracket">[</span><!-- -->{{join|separator=<span class="mw-editsection-divider"> &amp;#124; </span> |1={{#ifexist: {{#rel2abs: {{{lc|}}} }} | {{#ifeq: {{{dislooklink|{{{noview|}}}}}} | yes || [[{{{lc}}}|просмотр]] }} }} |2={{#ifexist: {{#rel2abs: {{{lc|}}} }} | [[Special:EditPage/{{#rel2abs: {{{lc}}} }}|править]] }} |3={{#ifexist: {{#rel2abs: {{{lc|}}} }} | {{#ifeq: {{{dishistlink|{{{nohistory|}}}}}} | yes || [[Special:PageHistory/{{#rel2abs: {{{lc}}} }}|история]] }} }} |4={{#ifexist: {{#rel2abs: {{{lc|}}} }} | | [{{fullurl:{{#rel2abs: {{{lc}}} }}|action=edit&redlink=1}} создать] }} |5={{#ifeq: {{{diswatchlink|{{{nowatch|}}}}}} | yes || [{{fullurl:{{#rel2abs: {{{lc}}} }}|action=watch}} следить] }} |6={{#ifeq: {{{disupdlink|{{{noupdate|}}}}}} | yes || {{очистить кэш|обновить|nocat=1}}</span> }} }}<span class="mw-editsection-bracket">]</span></div><noinclude> {{doc}} </noinclude> 9ee2c9eed92e2ecc9377a7b9486ad8bc214a83d4 Шаблон:Действия для страницы/styles.css 10 175 393 392 2024-08-10T15:21:19Z DuOfOrl 5 1 версия импортирована sanitized-css text/css .ts-tlinks-tlinks { font-weight: normal; float: right; line-height: inherit; } .ts-tlinks-tlinks .mw-editsection-divider { display: inline; } /* [[Категория:Шаблоны:Подстраницы CSS]] */ a003e896d263c29e66d2246b210e5d73e577ea46 Шаблон:Doc/end 10 176 395 394 2024-08-10T15:21:19Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <includeonly></div> </div><templatestyles src="Шаблон:Doc/styles.css" />{{#ifexpr: {{NAMESPACENUMBER}} mod 2 = 1 <!-- Например, [[Обсуждение MediaWiki:Robots.txt]] --> | {{^|1em}} | <div class="ts-doc-footer plainlinks"> {{#ifeq: {{str left|{{PAGENAME}}|9}} | Песочница | | {{#ifeq: {{str rightc|{{PAGENAME}}|10}} | /песочница | | Во избежание поломок страниц, использующих этот {{#ifeq: {{NAMESPACE}} | Модуль | модуль | шаблон }}, экспериментируйте в [[Википедия:Правка и тестирование шаблонов в песочнице|песочнице]] <small style="font-style:normal;">({{#ifexist: {{FULLPAGENAME}}/песочница | [{{fullurl:{{FULLPAGENAME}}/песочница|action=edit}} редактировать] {{!}} [{{fullurl:Special:ComparePages|page1={{FULLPAGENAMEE}}&page2={{FULLPAGENAMEE}}/песочница}} разница] {{#ifexist: {{FULLPAGENAME}}/тесты | {{!}} [[{{FULLPAGENAME}}/тесты|тесты]] }} | {{#ifeq: {{NAMESPACE}} | Модуль | [{{fullurl:{{FULLPAGENAME}}/песочница|action=edit}} создать] | [{{fullurl:{{FULLPAGENAME}}/песочница|action=edit&preload=Шаблон:Doc/предзагрузка-песочница}} создать] {{!}} [{{fullurl:{{FULLPAGENAME}}/песочница|action=edit&preload=Шаблон:Doc/зеркало}} зеркало] }} }})</small> или {{#ifeq: {{NAMESPACE}} | Модуль | [[Модуль:Песочница|песочнице для модулей]] | своём [[ВП:ЛП|личном пространстве]] }}.<br> }} }}{{#ifexist: {{FULLPAGENAME}}/doc | Пожалуйста, добавляйте категории на подстраницу [[/doc]].&#32;}}[[Special:PrefixIndex/{{FULLPAGENAME}}/|Подстраницы этого {{#ifeq: {{NAMESPACE}} | Модуль | модуля | шаблона }}]]. </div> }}</includeonly><noinclude>{{doc}}</noinclude> 758a01a3d76e14ef14b2b0ee047ac47ddac8fd8e Шаблон:Lang-sv 10 177 397 396 2024-08-10T15:21:20Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki [[шведский язык|швед.]] {{langi|sv|{{{1}}}}}<noinclude>{{doc|Lang/doc}} </noinclude> c4b5e81c6405972dcea4cc26ab77e99e9bd2021f Шаблон:Docpage 10 178 399 398 2024-08-10T15:21:20Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <includeonly>{{#ifeq: {{SUBPAGENAME}} | doc | {{fmbox | class = hlist nowraplinks | style = margin-bottom:1em; background:var(--background-color-progressive-subtle, #eaf3ff); color:inherit; border:1px solid var(--border-color-content-added, #a3d3ff); | image = [[Файл:OOjs UI icon info.svg|24px|link=|alt=|class=skin-invert-image]] | text = <div> * [[:{{#titleparts: {{SUBJECTPAGENAME}} | -1 }}]] * [[:{{SUBJECTPAGENAME}}|Документация]] * [[{{#titleparts: {{TALKPAGENAME}} | -1 }}|Обсуждение]] * [[Служебная:Whatlinkshere/{{#titleparts: {{SUBJECTPAGENAME}} | -1 }}|Где используется]] {{#ifeq: {{NAMESPACE}} | {{ns:Template}} | ** {{Параметры шаблона|{{#titleparts: {{PAGENAME}} | -1 }}}} }}</div><!-- -->{{#if: {{{nocat|}}} || {{#ifexist: {{NAMESPACE}}:{{BASEPAGENAME}} || [[Категория:Шаблоны:Документация несуществующих шаблонов]] }} }} }}{{#if: {{{nocat|}}} || {{#ifeq: {{NAMESPACE}} | Модуль | [[Категория:Модули:Документация]] | [[Категория:Шаблоны:Документация]] }} }} }}</includeonly><noinclude>{{doc}}</noinclude> 9b09d5b771c19e45bd038d248dcf31e500e436ce Шаблон:Очистить кэш 10 179 401 400 2024-08-10T15:21:21Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <!-- Класс purgelink и атрибут data-pagename используются в [[MediaWiki:Common.js]], чтобы очищать кэш без перехода на отдельную страницу --><span class="noprint purgelink" {{#if: {{{2|}}} | data-pagename="{{{2}}}" }}>{{выполнить скрипт|purgeLink}}[[Special:Purge/{{#if: {{{2|}}} | {{{2}}} | {{FULLPAGENAME}} }}|{{#if: {{{1|}}} | {{{1}}} | Очистить кэш }}]]</span>{{#ifeq: {{NAMESPACE}}{{{nocat|}}} | {{ns:10}} <!-- Шаблон --> | {{очищать кэш|ежедневно}} }}<noinclude>{{doc}}</noinclude> be6695060ca61d2125386d02d3a19109c0e7c27b Шаблон:Население государства 10 180 403 402 2024-08-10T15:21:22Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <includeonly>{{#switch: {{{1}}} | Республика Южная Осетия = Население Южной Осетии{{!}}Население | Население }}</includeonly><noinclude> {{doc}} [[Категория:Шаблоны по странам]] </noinclude> e0568280ef5056e94f5f1abf1934f4188a52c35f Шаблон:Lang-fi 10 181 405 404 2024-08-10T15:21:22Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki [[финский язык|фин.]] {{langi|fi|{{{1}}}}}<noinclude>{{doc|Lang/doc}} </noinclude> 16ac91b8e1e294e7687d57c0757c178f9662581c Шаблон:Выполнить скрипт 10 182 407 406 2024-08-10T15:21:23Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{#switch: {{{1|}}} | = | mainPage = [[Категория:Википедия:Заглавная страница|{{NAMESPACENUMBER}}]] | #default = {{#ifexist: Категория:Википедия:Страницы с гаджетом по требованию {{{1}}} | [[Категория:Википедия:Страницы с гаджетом по требованию {{{1}}}|{{NAMESPACENUMBER}}]] }} }}<noinclude> {{doc}} </noinclude> 6979ea0342067dc76b9adcb9a5e072207c2c5a63 Модуль:Demo 828 183 409 408 2024-08-10T15:21:24Z DuOfOrl 5 1 версия импортирована Scribunto text/plain local p = {} local getArgs = require('Модуль:Arguments').getArgs local function hasValue(param) if param and param:find('%S') then return true end end --creates a frame object that cannot access any of the parent's args --unless a table containing a list keys of not to inherit is provided function disinherit(frame, onlyTheseKeys) local parent = frame:getParent() or frame local orphan = parent:newChild{} orphan.getParent = parent.getParent --returns nil orphan.args = {} if onlyTheseKeys then local family = {parent, frame} for f = 1, 2 do for k, v in pairs(family[f] and family[f].args or {}) do orphan.args[k] = orphan.args[k] or v end end parent.args = mw.clone(orphan.args) setmetatable(orphan.args, nil) for _, k in ipairs(onlyTheseKeys) do rawset(orphan.args, k, nil) end end return orphan, parent end function p.get(frame, arg, passArgs) local orphan, frame = disinherit(frame, passArgs and {arg or 1}) local code, noWiki, preserve = frame.args[arg or 1] or '' local kill_categories = not frame.args.save_categories local tag, sep if code:match'nowiki' then local placeholder, preserve = ('6'):char(), {} -- We replace "&#125;%-" and "%-&#123;" because of some server bug probably connected to -- [[mw:Parsoid/MediaWiki DOM spec/Language conversion blocks]] and leading to -- =mw.text.unstripNoWiki(mw.getCurrentFrame():preprocess('<nowiki>}-</nowiki>')) -- outputting '&#125;-' instead of "}-", while it's ok with "<nowiki>} -</nowiki>" code = mw.text.unstripNoWiki(code) :gsub('&lt;', '<') :gsub('&gt;', '>') :gsub('&#125;%-', '}-') :gsub('%-&#123;', '-{') if (mw.text.trim(code):match'\n') then tag = 'pre' sep = '' end noWiki = code:gsub('%%', placeholder) for k in noWiki:gmatch('&.-;') do table.insert(preserve, (k:gsub('&', '&amp;'))) noWiki = noWiki:gsub('(&.-;)', '%%%s') end noWiki = mw.text.nowiki(noWiki):format(unpack(preserve)):gsub(placeholder, '%%') end return { source = noWiki or code, output = orphan:preprocess(code) :gsub(kill_categories and '%[%[Категория:.-%]%]' or '', '') :gsub(kill_categories and '%[%[К:.-%]%]' or '', '') :gsub(kill_categories and '%[%[Category:.-%]%]' or '', ''), frame = frame, args = getArgs(frame), tag = tag, sep = sep } end function p.main(frame, demoTable) local show = demoTable or p.get(frame) local args = show.args local yesno = require('Module:Yesno') args.reverse = yesno(args.reverse, false) args.tag = hasValue(args.tag) and args.tag or hasValue(show.tag) and show.tag or "code" args.sep = args.sep or args.br or show.sep args.sep = tonumber(args.sep) and ('<br>'):rep(args.sep or 0) or args.sep or (args.tag == 'pre' and '' or ' → ') if show[args.result_arg] then return show[args.result_arg] end return args.reverse and string.format( '%s%s<%s%s%s>%s</%s>', show.output, args.sep, args.tag, hasValue(args.class) and string.format(' class="%s"', args.class) or '', hasValue(args.style) and string.format(' style="%s"', args.style) or '', show.source, args.tag ) or string.format( '<%s%s%s>%s</%s>%s%s', args.tag, hasValue(args.class) and string.format(' class="%s"', args.class) or '', hasValue(args.style) and string.format(' style="%s"', args.style) or '', show.source, args.tag, args.sep, show.output ) end --passing of args into other module without preprocessing function p.module(frame) local orphan, frame = disinherit(frame, { 'demo_template', 'demo_module', 'demo_module_func', 'demo_main', 'demo_br', 'demo_result_arg', 'demo_save_categories' }) local template = frame.args.demo_template and 'Template:'..frame.args.demo_template local demoFunc = frame.args.demo_module_func or 'main\n' local demoModule = require('Module:' .. frame.args.demo_module)[demoFunc:match('^%s*(.-)%s*$')] frame.args.br, frame.args.result_arg = frame.args.demo_br or frame.args.demo_sep, frame.args.demo_result_arg local kill_categories = not save_categories if demoModule then local named = {insert = function(self, ...) table.insert(self, ...) return self end} local source = {insert = named.insert, '{{', frame.args.demo_template or frame.args.demo_module, '\n'} if not template then source:insert(2, '#invoke:'):insert(4, '|'):insert(5, demoFunc) end local insertNamed = #source + 1 for k, v in pairs(orphan.args) do local nan, insert = type(k) ~= 'number', {v} local target = nan and named or source target:insert'|' if nan then target:insert(k):insert'=':insert'\n' table.insert(insert, 1, #target) end target:insert(unpack(insert)) local nowiki = v:match('nowiki') if nowiki or v:match('{{.-}}') then orphan.args[k] = frame:preprocess(nowiki and mw.text.unstripNoWiki(v) or v) end end source:insert'}}' table.insert(source, insertNamed, table.concat(named)) return p.main(orphan, { source = mw.text.encode(table.concat(source), "<>'|=~"), output = tostring(demoModule(orphan)):gsub(kill_categories and '%[%[Категория:.-%]%]' or '', ''):gsub(kill_categories and '%[%[К:.-%]%]' or '', ''):gsub(kill_categories and '%[%[Category:.-%]%]' or '', ''), frame = frame }) else return "ERROR: Invalid module function: "..demoFunc end end return p 9beaf8f8041a39ae73ba17b2f70609171c4196d3 Шаблон:Государство/doc 10 184 411 410 2024-08-10T15:21:26Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{docpage}} Этот [[Википедия:Шаблоны-карточки|шаблон-карточка]] используется для вставки карточки в статьи о современных государствах; * для исторических государств используйте {{t|историческое государство}}. * для составных частей государств используйте {{t|Административная единица}}. == Образец для копирования == <pre> {{Государство |Статус = <!-- виртуальное / непризнанное / частично признанное / регион; для признанных государств не заполнять --> |Русское название = |Оригинальное название = |Родительный падеж = |Герб = |Вместо герба = |Девиз = {{lang-??2|}}<!-- на оф. языке / языках гос-ва --> |Перевод девиза = |Название гимна = |Перевод названия гимна = |Аудио = |Форма правления = |Государственный строй = |Государственная религия = |На карте = |подпись к карте = |На карте2 = |Язык/Языки = |Основано/Основана = |Дата/Даты независимости = |Независимость от = |Столица = |Крупнейшие города = |Должность руководителя 1 = |Руководитель 1 = |Должность руководителя 2 = |Руководитель 2 = |Должность руководителя 3 = |Руководитель 3 = |Должность руководителя 4 = |Руководитель 4 = |Должность руководителя 5 = |Руководитель 5 = |Место по территории = |Территория = |Процент воды = |Этнохороним = |Место по населению = |Население = |Год оценки = |Население по переписи = |Год переписи = |Плотность населения = |Место по плотности = |ВВП (ППС) = |Год расчёта ВВП (ППС) = |Место по ВВП (ППС) = |ВВП (ППС) на душу населения = |Место по ВВП (ППС) на душу населения = |ВВП (номинал) = |Год расчёта ВВП (номинал) = |Место по ВВП (номинал) = |ВВП (номинал) на душу населения = |Место по ВВП (номинал) на душу населения = |ИРЧП = |Год расчёта ИРЧП = |Место по ИРЧП = |Уровень ИРЧП = |Валюта = |Домен/Домены = |Телефонный код = |Часовой пояс = |Автомобильное движение = |Примечания = <!-- |Без флага и герба=* --> <!-- |Без гимна=* --> }} </pre> == Описание параметров == Некоторые параметры могут быть заданы в разных формах (например, в единственном либо множественном числе). После копирования образца в статью заполните только строку с более подходящей формой. Например, в статье [[Албания]]&nbsp;— <pre> |Язык = [[Албанский язык|албанский]]</pre> а в статье [[Канада]]&nbsp;— <pre> |Языки = [[Английский язык|английский]] и [[Французский язык|французский]]</pre> Для статей о регионах с нечётким правовым статусом используйте параметр <code>Спорный статус = да</code> и параметры «Основано», «Дата образования», «Провозглашение независимости» и «Дипломатическое признание» вместо «Дата независимости» и «Основано»: <pre> |Спорный статус = да |Основано = |Основана = |Дата образования = |Провозглашение независимости = |Дипломатическое признание = |Независимость от = </pre> Для статей о [[Непризнанные и частично признанные государства|непризнанных государствах]] или [[Автономный регион|автономных регионах]], не являющихся самостоятельными государствами, используйте параметр <code>Статус&nbsp;=&nbsp;непризнанное</code> или <code>Статус = регион</code>, это отключит автоматическое добавление категории [[:Категория:Государства по алфавиту|Государства по алфавиту]], а в первом случае также добавит категорию [[:Категория:Непризнанные государства|Непризнанные государства]]. Для статей о [[Виртуальное государство|виртуальных государствах]] используйте параметр <code>Статус = виртуальное</code>, это добавит категорию [[:Категория:Виртуальные государства|Виртуальные государства]]. == Пример использования == {{demo|reverse=1|br=|<nowiki>{{Государство |Русское название = Финляндская Республика |Оригинальное название = {{lang-fi|Suomen Tasavalta}}<br>{{lang-sv|Republiken Finland}} |Родительный падеж = Финляндии |Герб = Coat of arms of Finland.svg |Флаг = Flag of Finland.svg<!-- иначе используется конструкция {{флаг|{{FULLPAGENAME}}|размер=135px}} --> |Вместо герба = |Девиз = |Перевод девиза = |Название гимна = Maamme |Перевод названия гимна = Наш край |Аудио = |Форма правления = [[президентская республика]] |Государственный строй = [[унитарное государство]] |Государственная религия = |На карте = EU-Finland.svg |подпись к карте = Расположение '''Финляндии''' (тёмно-зелёный):<br>— в [[Европа|Европе]] (светло-зелёный и тёмно-серый)<br>— в [[Европейский союз|Европейском союзе]] (светло-зелёный) |На карте2 = |Языки = [[финский язык|финский]], [[шведский язык|шведский]] |Основано/Основана = |Дата независимости = [[6 декабря]] [[1917]] |Независимость от = [[Россия|России]] |Столица = [[Хельсинки]] |Крупнейший город = Хельсинки |Должность руководителя 1 = [[Президент Финляндии|Президент]] |Руководитель 1 = [[Халонен, Тарья Каарина|Тарья Халонен]] |Должность руководителя 2 = [[Премьер-министр Финляндии|Премьер-министр]] |Руководитель 2 = [[Ванханен, Матти Танели|Матти Ванханен]] |Место по территории = 63 |Территория = 338 145 |Процент воды = 9,96 |Этнохороним = финляндец, финляндка |Место по населению = 106 |Население = 5 219 732 |Год оценки = 2003 |Население по переписи = |Год переписи = |Плотность населения = 15,4 |Место по плотности = |ВВП = |Год расчёта ВВП = |Место по ВВП = |ВВП на душу населения = |Место по ВВП на душу населения = |ИРЧП = |Год расчёта ИРЧП = |Место по ИРЧП = |Уровень ИРЧП = |Валюта = [[евро]]<ref name="money">до 2002 — [[финская марка]]</ref> |Домены = [[.fi]], [[.ax]] (для [[Аландские острова|Аландских островов]]) |Телефонный код = 358 |Часовой пояс = +2 |Автомобильное движение = |Примечания = <references/> }}</nowiki>}} == TemplateData == <templatedata> { "params": { "Спорный статус": {}, "Статус": {}, "Русское название": {}, "Оригинальное название": {}, "Флаг": { "type": "wiki-file-name" }, "Ссылка на флаг": {}, "Родительный падеж": {}, "Герб": { "type": "wiki-file-name" }, "Отображаемая подпись герба": {}, "Вместо герба": {}, "Девиз": {}, "Перевод девиза": {}, "Без гимна": {}, "Название гимна": {}, "Перевод названия гимна": {}, "Аудио": {}, "На карте": {}, "На карте2": {}, "Дата1": {}, "Дата2": {}, "Дата3": {}, "Дата4": {}, "Дата5": {}, "Дата6": {}, "Дата7": {}, "Дата8": {}, "Дата9": {}, "Дата10": {}, "Дата11": {}, "Дата12": {}, "sovereignty_type": {}, "Этап1": {}, "Этап2": {}, "Этап3": {}, "Этап4": {}, "Этап5": {}, "Этап6": {}, "Этап7": {}, "Этап8": {}, "Этап9": {}, "Этап10": {}, "Этап11": {}, "Этап12": {}, "Основана": {}, "Основано": {}, "Дата образования": {}, "Провозглашение независимости": {}, "Независимость от": {}, "Дипломатическое признание": {}, "Отображаемый тип независимости": {}, "Даты независимости": {}, "Дата независимости": {}, "Язык": {}, "Языки": {}, "Столица": {}, "Крупнейший город": {}, "Крупнейшие города": {}, "Форма правления": {}, "Должность руководителя 1": {}, "Должности руководителей": {}, "Руководитель 1": {}, "Руководители": {}, "Должность руководителя 2": {}, "Руководитель 2": {}, "Должность руководителя 3": {}, "Руководитель 3": {}, "Должность руководителя 4": {}, "Руководитель 4": {}, "Должность руководителя 5": {}, "Руководитель 5": {}, "Государственная религия": {}, "Место по территории": {}, "Территория": {}, "Процент воды": {}, "Территория2": {}, "Население": {}, "Год оценки": {}, "Год переписи": {}, "Население2": {}, "Место по населению": {}, "Население по переписи": {}, "Плотность населения": {}, "Место по плотности": {}, "ВВП": {}, "Год расчёта ВВП": {}, "Место по ВВП": {}, "ВВП на душу населения": {}, "Место по ВВП на душу населения": {}, "ВВП (ППС)": {}, "Год расчёта ВВП (ППС)": {}, "Место по ВВП (ППС)": {}, "ВВП (ППС) на душу населения": {}, "Место по ВВП (ППС) на душу населения": {}, "ВВП (номинал)": {}, "Год расчёта ВВП (номинал)": {}, "Место по ВВП (номинал)": {}, "ВВП (номинал) на душу населения": {}, "Место по ВВП (номинал) на душу населения": {}, "Год расчёта ИРЧП": {}, "ИРЧП": {}, "Уровень ИРЧП": {}, "Место по ИРЧП": {}, "Этнохороним": {}, "Валюта": {}, "Домены": {}, "Домен": {}, "Телефонный код": {}, "Часовые пояса": {}, "Часовой пояс": {}, "Примечания": {}, "nocat": { "type": "boolean" }, "lat_deg": {}, "lat_min": {}, "lat_sec": {}, "lat_dir": {}, "lon_deg": {}, "lon_min": {}, "lon_sec": {}, "lon_dir": {}, "region": {}, "CoordScale": {}, "Размер герба": { "aliases": [ "размер герба" ], "type": "number" }, "Размер флага": { "aliases": [ "размер флага" ], "type": "number" }, "Размер карты": { "aliases": [ "размер карты" ] }, "Подпись к карте": { "aliases": [ "подпись к карте" ] }, "Размер карты2": { "aliases": [ "размер карты2" ] }, "Государственный строй": {}, "Автомобильное движение": {} }, "paramOrder": [ "Статус", "Спорный статус", "Русское название", "Оригинальное название", "Флаг", "Размер флага", "Ссылка на флаг", "Родительный падеж", "Герб", "Размер герба", "Отображаемая подпись герба", "Вместо герба", "Девиз", "Перевод девиза", "Без гимна", "Название гимна", "Перевод названия гимна", "Аудио", "На карте", "Размер карты", "Подпись к карте", "На карте2", "Размер карты2", "Дата1", "Дата2", "Дата3", "Дата4", "Дата5", "Дата6", "Дата7", "Дата8", "Дата9", "Дата10", "Дата11", "Дата12", "sovereignty_type", "Этап1", "Этап2", "Этап3", "Этап4", "Этап5", "Этап6", "Этап7", "Этап8", "Этап9", "Этап10", "Этап11", "Этап12", "Основана", "Основано", "Дата образования", "Провозглашение независимости", "Независимость от", "Дипломатическое признание", "Отображаемый тип независимости", "Даты независимости", "Дата независимости", "Язык", "Языки", "Столица", "Крупнейший город", "Крупнейшие города", "Форма правления", "Государственный строй", "Должность руководителя 1", "Должности руководителей", "Руководитель 1", "Руководители", "Должность руководителя 2", "Руководитель 2", "Должность руководителя 3", "Руководитель 3", "Должность руководителя 4", "Руководитель 4", "Должность руководителя 5", "Руководитель 5", "Государственная религия", "Место по территории", "Территория", "Процент воды", "Территория2", "Население", "Год оценки", "Год переписи", "Население2", "Место по населению", "Население по переписи", "Плотность населения", "Место по плотности", "ВВП", "Год расчёта ВВП", "Место по ВВП", "ВВП на душу населения", "Место по ВВП на душу населения", "ВВП (ППС)", "Год расчёта ВВП (ППС)", "Место по ВВП (ППС)", "ВВП (ППС) на душу населения", "Место по ВВП (ППС) на душу населения", "ВВП (номинал)", "Год расчёта ВВП (номинал)", "Место по ВВП (номинал)", "ВВП (номинал) на душу населения", "Место по ВВП (номинал) на душу населения", "Год расчёта ИРЧП", "ИРЧП", "Уровень ИРЧП", "Место по ИРЧП", "Этнохороним", "Валюта", "Домены", "Домен", "Телефонный код", "Часовые пояса", "Часовой пояс", "Автомобильное движение", "Примечания", "lat_deg", "lat_min", "lat_sec", "lat_dir", "lon_deg", "lon_min", "lon_sec", "lon_dir", "region", "CoordScale", "nocat" ], "format": "block" } </templatedata> == См. также == * {{tl|Историческое государство}} <includeonly> [[Категория:Шаблоны-карточки:Географические объекты]] </includeonly> b1e2b1107db0671d3bcc4dda5bd29020192c442e Шаблон:Историческое государство 10 185 413 412 2024-08-10T16:55:56Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{Карточка |имя = Историческое государство |from = {{{from|}}} |стиль_тела = width:28em; |стиль_заголовков = |вверху0 = {{#if: {{{статус|}}} | {{{статус}}} | Историческое государство }} |вверху = {{Карточка/название|{{{название|}}}|from={{{from|}}}}} |вверху2 = {{Карточка/оригинал названия|{{{самоназвание|}}}|from={{{from|}}}}} |текст1 = {{Карточка/флаг и герб | флаг = {{{флаг|}}} | флаг подпись = {{{описание_флага|}}} | герб = {{{герб|}}} | герб подпись = {{{описание_герба|}}} |from={{{from|}}}}} |текст2 = {{#if: {{{девиз|}}} | [[Девиз]]: ''«{{{девиз}}}»''{{#if: {{{перевод девиза|}}}|<br />''«{{{перевод девиза}}}»''}} }} |текст3 = {{if-wikidata|p85|{{{гимн|}}}|[[Государственный гимн|Гимн]]: {{wikidata|p85|{{{гимн|}}}|from={{{from|}}}}}|from={{{from|}}}}} |викиданные3 = p85 |текст4 = {{wikidata|p242[1]|{{{карта|}}}|size={{{размер|}}}|caption={{{описание|}}}|from={{{from|}}}}} |заголовок5 = <div style="float:left; margin-right:0.5em; text-align:left; width:4em;"><!-- -->{{#if:{{{p8|}}}{{{successionbelow|}}}|[[#before-after|↓]]|<!-- -->{{#if:{{{p1|}}}|{{nobr|[[{{{p1}}}|←]]&nbsp;{{#if:{{{flag_p1|}}}|[[Файл:{{{flag_p1|}}}|border|30px|link={{{p1|}}}]]|{{#if:{{{image_p1|}}}|{{{image_p1}}}|[[Файл:Flag of None.svg|30px|border]]}}}}}}}}<!-- -->{{#if:{{{p2|}}}|<br>{{nobr|[[{{{p2}}}|←]]&nbsp;{{#if:{{{flag_p2|}}}|[[Файл:{{{flag_p2}}}|border|30px|link={{{p2|}}}]]|{{#if:{{{image_p2|}}}|{{{image_p2}}}|[[Файл:Flag of None.svg|30px|border]]}}}}}}}}<!-- -->{{#if:{{{p3|}}}|<br>{{nobr|[[{{{p3}}}|←]]&nbsp;{{#if:{{{flag_p3|}}}|[[Файл:{{{flag_p3}}}|border|30px|link={{{p3|}}}]]|{{#if:{{{image_p3|}}}|{{{image_p3}}}|[[Файл:Flag of None.svg|30px|border]]}}}}}}}}<!-- -->{{#if:{{{p4|}}}|<br>{{nobr|[[{{{p4}}}|←]]&nbsp;{{#if:{{{flag_p4|}}}|[[Файл:{{{flag_p4}}}|border|30px|link={{{p4|}}}]]|{{#if:{{{image_p4|}}}|{{{image_p4}}}|[[Файл:Flag of None.svg|30px|border]]}}}}}}}}<!-- -->{{#if:{{{p5|}}}|<br>{{nobr|[[{{{p5}}}|←]]&nbsp;{{#if:{{{flag_p5|}}}|[[Файл:{{{flag_p5}}}|border|30px|link={{{p5|}}}]]|{{#if:{{{image_p5|}}}|{{{image_p5}}}|[[Файл:Flag of None.svg|30px|border]]}}}}}}}}<!-- -->{{#if:{{{p6|}}}|<br>{{nobr|[[{{{p6}}}|←]]&nbsp;{{#if:{{{flag_p6|}}}|[[Файл:{{{flag_p6}}}|border|30px|link={{{p6|}}}]]|{{#if:{{{image_p6|}}}|{{{image_p6}}}|[[Файл:Flag of None.svg|30px|border]]}}}}}}}}<!-- -->{{#if:{{{p7|}}}|<br>{{nobr|[[{{{p7}}}|←]]&nbsp;{{#if:{{{flag_p7|}}}|[[Файл:{{{flag_p7}}}|border|30px|link={{{p7|}}}]]|{{#if:{{{image_p7|}}}|{{{image_p7}}}|[[Файл:Flag of None.svg|30px|border]]}}}}}}}}}}<!-- --></div> <div style="float:right; margin-left:0.5em; text-align:right; width:4em;"><!-- -->{{#if:{{{s8|}}}{{{successionbelow|}}}|[[#before-after|↓]]|<!-- -->{{#if:{{{s1|}}}|{{nobr|{{#if:{{{flag_s1|}}}|[[Файл:{{{flag_s1}}}|border|30px|link={{{s1|}}}]]|{{#if:{{{image_s1|}}}|{{{image_s1}}}|[[Файл:Flag of None.svg|30px|border]]}}}}&nbsp;[[{{{s1}}}|→]]}}}}<!-- -->{{#if:{{{s2|}}}|<br>{{nobr|{{#if:{{{flag_s2|}}}|[[Файл:{{{flag_s2}}}|border|30px|link={{{s2|}}}]]|{{#if:{{{image_s2|}}}|{{{image_s2}}}|[[Файл:Flag of None.svg|30px|border]]}}}}&nbsp;[[{{{s2}}}|→]]}}}}<!-- -->{{#if:{{{s3|}}}|<br>{{nobr|{{#if:{{{flag_s3|}}}|[[Файл:{{{flag_s3}}}|border|30px|link={{{s3|}}}]]|{{#if:{{{image_s3|}}}|{{{image_s3}}}|[[Файл:Flag of None.svg|30px|border]]}}}}&nbsp;[[{{{s3}}}|→]]}}}}<!-- -->{{#if:{{{s4|}}}|<br>{{nobr|{{#if:{{{flag_s4|}}}|[[Файл:{{{flag_s4}}}|border|30px|link={{{s4|}}}]]|{{#if:{{{image_s4|}}}|{{{image_s4}}}|[[Файл:Flag of None.svg|30px|border]]}}}}&nbsp;[[{{{s4}}}|→]]}}}}<!-- -->{{#if:{{{s5|}}}|<br>{{nobr|{{#if:{{{flag_s5|}}}|[[Файл:{{{flag_s5}}}|border|30px|link={{{s5|}}}]]|{{#if:{{{image_s5|}}}|{{{image_s5}}}|[[Файл:Flag of None.svg|30px|border]]}}}}&nbsp;[[{{{s5}}}|→]]}}}}<!-- -->{{#if:{{{s6|}}}|<br>{{nobr|{{#if:{{{flag_s6|}}}|[[Файл:{{{flag_s6}}}|border|30px|link={{{s6|}}}]]|{{#if:{{{image_s6|}}}|{{{image_s6}}}|[[Файл:Flag of None.svg|30px|border]]}}}}&nbsp;[[{{{s6}}}|→]]}}}}<!-- -->{{#if:{{{s7|}}}|<br>{{nobr|{{#if:{{{flag_s7|}}}|[[Файл:{{{flag_s7}}}|border|30px|link={{{s7|}}}]]|{{#if:{{{image_s7|}}}|{{{image_s7}}}|[[Файл:Flag of None.svg|30px|border]]}}}}&nbsp;[[{{{s7}}}|→]]}}}}}}<!-- --></div> {{#if: {{wikidata|p571|{{{образовано|}}}|plain=true|from={{{from|}}}}} {{wikidata|p576|{{{ликвидировано|}}}|plain=true|from={{{from|}}}}} | <div style="margin:0 4em;">{{nobr|{{wikidata|p571|{{{образовано|}}}|from={{{from|}}}}}&nbsp;—}} {{nobr|{{wikidata|p576|{{{ликвидировано|}}}|from={{{from|}}}}}}}</div> }} {{-}} |метка6 = [[Столица]] |текст6 = {{{столица|}}} |викиданные6 = p36 |метка7 = Крупнейшие города |текст7 = {{{города|}}} |викиданные7 = |метка8 = Язык(и) |текст8 = {{{язык|}}} |викиданные8 = p2936 |метка9 = [[Официальный язык]] |текст9 = {{{официальный язык|}}} |викиданные9 = p37 |метка10 = [[Религия]] |текст10 = {{{религия|}}} |викиданные10 = p3075 |метка11 = Денежная единица |текст11 = {{{валюта|}}} |викиданные11 = p38 |метка12 = Площадь |текст12 = {{{площадь|}}} |викиданные12 = p2046 |метка13 = Население |текст13 = {{{население|}}} |викиданные13 = p1082 |метка14 = Форма правления |текст14 = {{{форма_правления|}}} |викиданные14 = p122 |метка15 = Династия |текст15 = {{{династия|}}} |викиданные15 = |метка16 = {{{дополнительный_параметр}}} |текст16 = {{{содержимое_параметра|}}} |викиданные16 = |метка17 = {{{дополнительный_параметр1}}} |текст17 = {{{содержимое_параметра1|}}} |викиданные17 = |метка18 = {{{дополнительный_параметр2}}} |текст18 = {{{содержимое_параметра2|}}} |викиданные18 = |метка19 = {{{дополнительный_параметр3}}} |текст19 = {{{содержимое_параметра3|}}} |викиданные19 = |метка20 = {{{дополнительный_параметр4}}} |текст20 = {{{содержимое_параметра4|}}} |викиданные20 = |метка21 = {{{дополнительный_параметр5}}} |текст21 = {{{содержимое_параметра5|}}} |викиданные21 = |метка22 = {{{дополнительный_параметр6}}} |текст22 = {{{содержимое_параметра6|}}} |викиданные22 = |заголовок23 = {{#if: {{{титул_правителей2|}}}{{{титул_правителей3|}}}{{{титул_правителей4|}}}{{{титул_правителей5|}}}{{{титул_правителей6|}}}{{{титул_правителей7|}}}{{{титул_правителей8|}}}{{{титул_правителей9|}}}{{{титул_правителей10|}}}{{{титул_правителей11|}}}{{{титул_правителей12|}}}{{{титул_правителей13|}}}{{{титул_правителей14|}}}{{{титул_правителей15|}}}{{{титул_правителей16|}}} | Главы государства }} |заголовок24 = {{#if: {{{правитель1|}}} | {{{титул_правителя1|{{{титул_правителей}}}}}} }} |стиль_заголовка24 = {{#if: {{{титул_правителей2|}}}{{{титул_правителей3|}}}{{{титул_правителей4|}}}{{{титул_правителей5|}}}{{{титул_правителей6|}}}{{{титул_правителей7|}}}{{{титул_правителей8|}}}{{{титул_правителей9|}}}{{{титул_правителей10|}}}{{{титул_правителей11|}}}{{{титул_правителей12|}}}{{{титул_правителей13|}}}{{{титул_правителей14|}}}{{{титул_правителей15|}}}{{{титул_правителей16|}}} | background: transparent; padding-bottom:0; border-bottom:0; text-align:left; }} |метка25 = &nbsp;•&nbsp;{{{год_правителя1}}} |стиль_метки25 = font-weight:normal; {{#if: {{{титул_правителей2|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |текст25 = {{{правитель1|}}} |стиль_текста25 = {{#if: {{{титул_правителей2|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |викиданные25 = |заголовок26 = {{{титул_правителей2|}}} |стиль_заголовка26 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left; |метка27 = &nbsp;•&nbsp;{{{год_правителя2}}} |стиль_метки27 = font-weight:normal; {{#if: {{{титул_правителей3|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |текст27 = {{{правитель2|}}} |стиль_текста27 = {{#if: {{{титул_правителей3|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |викиданные27 = |заголовок28 = {{{титул_правителей3|}}} |стиль_заголовка28 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left; |метка29 = &nbsp;•&nbsp;{{{год_правителя3}}} |стиль_метки29 = font-weight:normal; {{#if: {{{титул_правителей4|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |текст29 = {{{правитель3|}}} |стиль_текста29 = {{#if: {{{титул_правителей4|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |викиданные29 = |заголовок30 = {{{титул_правителей4|}}} |стиль_заголовка30 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left; |метка31 = &nbsp;•&nbsp;{{{год_правителя4}}} |стиль_метки31 = font-weight:normal; {{#if: {{{титул_правителей5|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |текст31 = {{{правитель4|}}} |стиль_текста31 = {{#if: {{{титул_правителей5|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |викиданные31 = |заголовок32 = {{{титул_правителей5|}}} |стиль_заголовка32 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left; |метка33 = &nbsp;•&nbsp;{{{год_правителя5}}} |стиль_метки33 = font-weight:normal; {{#if: {{{титул_правителей6|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |текст33 = {{{правитель5|}}} |стиль_текста33 = {{#if: {{{титул_правителей6|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |викиданные33 = |заголовок34 = {{{титул_правителей6|}}} |стиль_заголовка34 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left; |метка35 = &nbsp;•&nbsp;{{{год_правителя6}}} |стиль_метки35 = font-weight:normal; {{#if: {{{титул_правителей7|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |текст35 = {{{правитель6|}}} |стиль_текста35 = {{#if: {{{титул_правителей7|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |викиданные35 = |заголовок36 = {{{титул_правителей7|}}} |стиль_заголовка36 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left; |метка37 = &nbsp;•&nbsp;{{{год_правителя7}}} |стиль_метки37 = font-weight:normal; {{#if: {{{титул_правителей8|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |текст37 = {{{правитель7|}}} |стиль_текста37 = {{#if: {{{титул_правителей8|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |викиданные37 = |заголовок38 = {{{титул_правителей8|}}} |стиль_заголовка38 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left; |метка39 = &nbsp;•&nbsp;{{{год_правителя8}}} |стиль_метки39 = font-weight:normal; {{#if: {{{титул_правителей9|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |текст39 = {{{правитель8|}}} |стиль_текста39 = {{#if: {{{титул_правителей9|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |викиданные39 = |заголовок40 = {{{титул_правителей9|}}} |стиль_заголовка40 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left; |метка41 = &nbsp;•&nbsp;{{{год_правителя9}}} |стиль_метки41 = font-weight:normal; {{#if: {{{титул_правителей10|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |текст41 = {{{правитель9|}}} |стиль_текста41 = {{#if: {{{титул_правителей10|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |викиданные41 = |заголовок42 = {{{титул_правителей10|}}} |стиль_заголовка42 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left; |метка43 = &nbsp;•&nbsp;{{{год_правителя10}}} |стиль_метки43 = font-weight:normal; {{#if: {{{титул_правителей11|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |текст43 = {{{правитель10|}}} |стиль_текста43 = {{#if: {{{титул_правителей11|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |викиданные43 = |заголовок44 = {{{титул_правителей11|}}} |стиль_заголовка44 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left; |метка45 = &nbsp;•&nbsp;{{{год_правителя11}}} |стиль_метки45 = font-weight:normal; {{#if: {{{титул_правителей12|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |текст45 = {{{правитель11|}}} |стиль_текста45 = {{#if: {{{титул_правителей12|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |викиданные45 = |заголовок46 = {{{титул_правителей12|}}} |стиль_заголовка46 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left; |метка47 = &nbsp;•&nbsp;{{{год_правителя12}}} |стиль_метки47 = font-weight:normal; {{#if: {{{титул_правителей13|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |текст47 = {{{правитель12|}}} |стиль_текста47 = {{#if: {{{титул_правителей13|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |викиданные47 = |заголовок48 = {{{титул_правителей13|}}} |стиль_заголовка48 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left; |метка49 = &nbsp;•&nbsp;{{{год_правителя13}}} |стиль_метки49 = font-weight:normal; {{#if: {{{титул_правителей14|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |текст49 = {{{правитель13|}}} |стиль_текста49 = {{#if: {{{титул_правителей14|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |викиданные49 = |заголовок50 = {{{титул_правителей14|}}} |стиль_заголовка50 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left; |метка51 = &nbsp;•&nbsp;{{{год_правителя14}}} |стиль_метки51 = font-weight:normal; {{#if: {{{титул_правителей15|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |текст51 = {{{правитель14|}}} |стиль_текста51 = {{#if: {{{титул_правителей15|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |викиданные51 = |заголовок52 = {{{титул_правителей15|}}} |стиль_заголовка52 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left; |метка53 = &nbsp;•&nbsp;{{{год_правителя15}}} |стиль_метки53 = font-weight:normal; {{#if: {{{титул_правителей16|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |текст53 = {{{правитель15|}}} |стиль_текста53 = {{#if: {{{титул_правителей16|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |викиданные53 = |заголовок54 = {{{титул_правителей16|}}} |стиль_заголовка54 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left; |метка55 = &nbsp;•&nbsp;{{{год_правителя16}}} |стиль_метки55 = font-weight:normal; padding-top:0; border-top:0; |текст55 = {{{правитель16|}}} |стиль_текста55 = padding-top:0; border-top:0; |викиданные55 = |заголовок56 = {{#if: {{{Этап1|}}} | История }} |метка57 = &nbsp;•&nbsp;{{nobr|{{{Дата1|}}}{{#if: {{{Дата1|}}} | {{sp}} }}{{{Год1|}}}}} |стиль_метки57 = font-weight:normal; {{#if: {{{Этап2|}}} | padding-bottom:0; border-bottom:0;}} |текст57 = {{{Этап1|}}} |стиль_текста57 = {{#if: {{{Этап2|}}} | padding-bottom:0; border-bottom:0;}} |викиданные57 = |метка58 = &nbsp;•&nbsp;{{nobr|{{{Дата2|}}}{{#if: {{{Дата2|}}} | {{sp}} }}{{{Год2|}}}}} |стиль_метки58 = font-weight:normal; {{#if: {{{Этап3|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |текст58 = {{{Этап2|}}} |стиль_текста58 = {{#if: {{{Этап3|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |викиданные58 = |метка59 = &nbsp;•&nbsp;{{nobr|{{{Дата3|}}}{{#if: {{{Дата3|}}} | {{sp}} }}{{{Год3|}}}}} |стиль_метки59 = font-weight:normal; {{#if: {{{Этап4|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |текст59 = {{{Этап3|}}} |стиль_текста59 = {{#if: {{{Этап4|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |викиданные59 = |метка60 = &nbsp;•&nbsp;{{nobr|{{{Дата4|}}}{{#if: {{{Дата4|}}} | {{sp}} }}{{{Год4|}}}}} |стиль_метки60 = font-weight:normal; {{#if: {{{Этап5|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |текст60 = {{{Этап4|}}} |стиль_текста60 = {{#if: {{{Этап5|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |викиданные60 = |метка61 = &nbsp;•&nbsp;{{nobr|{{{Дата5|}}}{{#if: {{{Дата5|}}} | {{sp}} }}{{{Год5|}}}}} |стиль_метки61 = font-weight:normal; {{#if: {{{Этап6|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |текст61 = {{{Этап5|}}} |стиль_текста61 = {{#if: {{{Этап6|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |викиданные61 = |метка62 = &nbsp;•&nbsp;{{nobr|{{{Дата6|}}}{{#if: {{{Дата6|}}} | {{sp}} }}{{{Год6|}}}}} |стиль_метки62 = font-weight:normal; {{#if: {{{Этап7|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |текст62 = {{{Этап6|}}} |стиль_текста62 = {{#if: {{{Этап7|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |викиданные62 = |метка63 = &nbsp;•&nbsp;{{nobr|{{{Дата7|}}}{{#if: {{{Дата7|}}} | {{sp}} }}{{{Год7|}}}}} |стиль_метки63 = font-weight:normal; {{#if: {{{Этап8|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |текст63 = {{{Этап7|}}} |стиль_текста63 = {{#if: {{{Этап8|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |викиданные63 = |метка64 = &nbsp;•&nbsp;{{nobr|{{{Дата8|}}}{{#if: {{{Дата8|}}} | {{sp}} }}{{{Год8|}}}}} |стиль_метки64 = font-weight:normal; {{#if: {{{Этап9|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |текст64 = {{{Этап8|}}} |стиль_текста64 = {{#if: {{{Этап9|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |викиданные64 = |метка65 = &nbsp;•&nbsp;{{nobr|{{{Дата9|}}}{{#if: {{{Дата9|}}} | {{sp}} }}{{{Год9|}}}}} |стиль_метки65 = font-weight:normal; {{#if: {{{Этап10|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |текст65 = {{{Этап9|}}} |стиль_текста65 = {{#if: {{{Этап10|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |викиданные65 = |метка66 = &nbsp;•&nbsp;{{nobr|{{{Дата10|}}}{{#if: {{{Дата10|}}} | {{sp}} }}{{{Год10|}}}}} |стиль_метки66 = font-weight:normal; {{#if: {{{Этап11|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |текст66 = {{{Этап10|}}} |стиль_текста66 = {{#if: {{{Этап11|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0; |викиданные66 = |метка67 = &nbsp;•&nbsp;{{nobr|{{{Дата11|}}}{{#if: {{{Дата11|}}} | {{sp}} }}{{{Год11|}}}}} |стиль_метки67 = font-weight:normal; padding-top:0; border-top:0; |текст67 = {{{Этап11|}}} |стиль_текста67 = padding-top:0; border-top:0; |викиданные67 = |заголовок68 = {{#if: {{{до|}}}{{{после|}}} | Преемственность }} |текст69 = {{#if: {{{до|}}} | ←&nbsp;[[{{{до}}}]] {{#if: {{{д1|}}} | ←&nbsp;[[{{{д1}}}]] }} {{#if: {{{д2|}}} | ←&nbsp;[[{{{д2}}}]] }} {{#if: {{{д3|}}} | ←&nbsp;[[{{{д3}}}]] }} {{#if: {{{д4|}}} | ←&nbsp;[[{{{д4}}}]] }} {{#if: {{{д5|}}} | ←&nbsp;[[{{{д5}}}]] }} {{#if: {{{д6|}}} | ←&nbsp;[[{{{д6}}}]] }} {{#if: {{{д7|}}} | ←&nbsp;[[{{{д7}}}]] }} }} |стиль_текста69 = text-align:left; |текст70 = {{#if: {{{после|}}} | [[{{{после}}}]]&nbsp;→ {{#if: {{{п1|}}} | [[{{{п1}}}]]&nbsp;→ }} {{#if: {{{п2|}}} | [[{{{п2}}}]]&nbsp;→ }} {{#if: {{{п3|}}} | [[{{{п3}}}]]&nbsp;→ }} {{#if: {{{п4|}}} | [[{{{п4}}}]]&nbsp;→ }} {{#if: {{{п5|}}} | [[{{{п5}}}]]&nbsp;→ }} {{#if: {{{п6|}}} | [[{{{п6}}}]]&nbsp;→ }} {{#if: {{{п7|}}} | [[{{{п7}}}]]&nbsp;→ }} }} |стиль_текста70 = text-align:right; |заголовок71 = {{#ifeq: {{#expr: {{#expr:{{#if:{{{p8|}}}|1|0}}+{{#if:{{{s8|}}}|1|0}}}}+{{#if:{{{successionbelow|}}}|1|0}} > 0}} | 1 | {{Видимый якорь|before-after|текст=Предшественники и преемники}} }} |текст72 = {{#ifeq: {{#expr: {{#expr:{{#if:{{{p8|}}}|1|0}}+{{#if:{{{s8|}}}|1|0}}}}+{{#if:{{{successionbelow|}}}|1|0}} > 0}} | 1 | <table style="display:table; margin:0; padding:0; table-layout:fixed; width:100%;"> <tr> <td style="padding-left:0;">{{#if: {{{p1|}}}{{{successionbelow|}}} | {{#if: {{{type_before|}}}{{{type_after|}}} | '''{{{type_before|Предшественники}}}''' }} * {{#if:{{{flag_p1|}}}|[[Файл:{{{flag_p1}}}|20px|border]]|{{#if:{{{image_p1|}}}|{{{image_p1}}}}}}} [[{{{p1}}}]]<!-- -->{{#if: {{{p2|}}} | * {{#if:{{{flag_p2|}}}|[[Файл:{{{flag_p2}}}|20px|border]]|{{#if:{{{image_p2|}}}|{{{image_p2}}}}}}} [[{{{p2}}}]] }}<!-- -->{{#if: {{{p3|}}} | * {{#if:{{{flag_p3|}}}|[[Файл:{{{flag_p3}}}|20px|border]]|{{#if:{{{image_p3|}}}|{{{image_p3}}}}}}} [[{{{p3}}}]] }}<!-- -->{{#if: {{{p4|}}} | * {{#if:{{{flag_p4|}}}|[[Файл:{{{flag_p4}}}|20px|border]]|{{#if:{{{image_p4|}}}|{{{image_p4}}}}}}} [[{{{p4}}}]] }}<!-- -->{{#if: {{{p5|}}} | * {{#if:{{{flag_p5|}}}|[[Файл:{{{flag_p5}}}|20px|border]]|{{#if:{{{image_p5|}}}|{{{image_p5}}}}}}} [[{{{p5}}}]] }}<!-- -->{{#if: {{{p6|}}} | * {{#if:{{{flag_p6|}}}|[[Файл:{{{flag_p6}}}|20px|border]]|{{#if:{{{image_p6|}}}|{{{image_p6}}}}}}} [[{{{p6}}}]] }}<!-- -->{{#if: {{{p7|}}} | * {{#if:{{{flag_p7|}}}|[[Файл:{{{flag_p7}}}|20px|border]]|{{#if:{{{image_p7|}}}|{{{image_p7}}}}}}} [[{{{p7}}}]] }}<!-- -->{{#if: {{{p8|}}} | * {{#if:{{{flag_p8|}}}|[[Файл:{{{flag_p8}}}|20px|border]]|{{#if:{{{image_p8|}}}|{{{image_p8}}}}}}} [[{{{p8}}}]] }}<!-- -->{{#if: {{{p9|}}} | * {{#if:{{{flag_p9|}}}|[[Файл:{{{flag_p9}}}|20px|border]]|{{#if:{{{image_p9|}}}|{{{image_p9}}}}}}} [[{{{p9}}}]] }}<!-- -->{{#if: {{{p10|}}} | * {{#if:{{{flag_p10|}}}|[[Файл:{{{flag_p10}}}|20px|border]]|{{#if:{{{image_p10|}}}|{{{image_p10}}}}}}} [[{{{p10}}}]] }}<!-- -->{{#if: {{{p11|}}} | * {{#if:{{{flag_p11|}}}|[[Файл:{{{flag_p11}}}|20px|border]]|{{#if:{{{image_p11|}}}|{{{image_p11}}}}}}} [[{{{p11}}}]] }}<!-- -->{{#if: {{{p12|}}} | * {{#if:{{{flag_p12|}}}|[[Файл:{{{flag_p12}}}|20px|border]]|{{#if:{{{image_p12|}}}|{{{image_p12}}}}}}} [[{{{p12}}}]] }}<!-- -->{{#if: {{{p13|}}} | * {{#if:{{{flag_p13|}}}|[[Файл:{{{flag_p13}}}|20px|border]]|{{#if:{{{image_p13|}}}|{{{image_p13}}}}}}} [[{{{p13}}}]] }}<!-- -->{{#if: {{{p14|}}} | * {{#if:{{{flag_p14|}}}|[[Файл:{{{flag_p14}}}|20px|border]]|{{#if:{{{image_p14|}}}|{{{image_p14}}}}}}} [[{{{p14}}}]] }}<!-- -->{{#if: {{{p15|}}} | * {{#if:{{{flag_p15|}}}|[[Файл:{{{flag_p15}}}|20px|border]]|{{#if:{{{image_p15|}}}|{{{image_p15}}}}}}} [[{{{p15}}}]] }} }}</td> <td style="padding-right:0;">{{#if: {{{s1|}}}{{{successionbelow|}}} | {{#if: {{{type_before|}}}{{{type_after|}}} | '''{{{type_after|Преемники}}}''' }} * {{#if:{{{flag_s1|}}}|[[Файл:{{{flag_s1}}}|20px|border]]|{{#if:{{{image_s1|}}}|{{{image_s1}}}}}}} [[{{{s1}}}]]<!-- -->{{#if: {{{s2|}}} | * {{#if:{{{flag_s2|}}}|[[Файл:{{{flag_s2}}}|20px|border]]|{{#if:{{{image_s2|}}}|{{{image_s2}}}}}}} [[{{{s2}}}]] }}<!-- -->{{#if: {{{s3|}}} | * {{#if:{{{flag_s3|}}}|[[Файл:{{{flag_s3}}}|20px|border]]|{{#if:{{{image_s3|}}}|{{{image_s3}}}}}}} [[{{{s3}}}]] }}<!-- -->{{#if: {{{s4|}}} | * {{#if:{{{flag_s4|}}}|[[Файл:{{{flag_s4}}}|20px|border]]|{{#if:{{{image_s4|}}}|{{{image_s4}}}}}}} [[{{{s4}}}]] }}<!-- -->{{#if: {{{s5|}}} | * {{#if:{{{flag_s5|}}}|[[Файл:{{{flag_s5}}}|20px|border]]|{{#if:{{{image_s5|}}}|{{{image_s5}}}}}}} [[{{{s5}}}]] }}<!-- -->{{#if: {{{s6|}}} | * {{#if:{{{flag_s6|}}}|[[Файл:{{{flag_s6}}}|20px|border]]|{{#if:{{{image_s6|}}}|{{{image_s6}}}}}}} [[{{{s6}}}]] }}<!-- -->{{#if: {{{s7|}}} | * {{#if:{{{flag_s7|}}}|[[Файл:{{{flag_s7}}}|20px|border]]|{{#if:{{{image_s7|}}}|{{{image_s7}}}}}}} [[{{{s7}}}]] }}<!-- -->{{#if: {{{s8|}}} | * {{#if:{{{flag_s8|}}}|[[Файл:{{{flag_s8}}}|20px|border]]|{{#if:{{{image_s8|}}}|{{{image_s8}}}}}}} [[{{{s8}}}]] }}<!-- -->{{#if: {{{s9|}}} | * {{#if:{{{flag_s9|}}}|[[Файл:{{{flag_s9}}}|20px|border]]|{{#if:{{{image_s9|}}}|{{{image_s9}}}}}}} [[{{{s9}}}]] }}<!-- -->{{#if: {{{s10|}}} | * {{#if:{{{flag_s10|}}}|[[Файл:{{{flag_s10}}}|20px|border]]|{{#if:{{{image_s10|}}}|{{{image_s10}}}}}}} [[{{{s10}}}]] }}<!-- -->{{#if: {{{s11|}}} | * {{#if:{{{flag_s11|}}}|[[Файл:{{{flag_s11}}}|20px|border]]|{{#if:{{{image_s11|}}}|{{{image_s11}}}}}}} [[{{{s11}}}]] }}<!-- -->{{#if: {{{s12|}}} | * {{#if:{{{flag_s12|}}}|[[Файл:{{{flag_s12}}}|20px|border]]|{{#if:{{{image_s12|}}}|{{{image_s12}}}}}}} [[{{{s12}}}]] }}<!-- -->{{#if: {{{s13|}}} | * {{#if:{{{flag_s13|}}}|[[Файл:{{{flag_s13}}}|20px|border]]|{{#if:{{{image_s13|}}}|{{{image_s13}}}}}}} [[{{{s13}}}]] }}<!-- -->{{#if: {{{s14|}}} | * {{#if:{{{flag_s14|}}}|[[Файл:{{{flag_s14}}}|20px|border]]|{{#if:{{{image_s14|}}}|{{{image_s14}}}}}}} [[{{{s14}}}]] }}<!-- -->{{#if: {{{s15|}}} | * {{#if:{{{flag_s15|}}}|[[Файл:{{{flag_s15}}}|20px|border]]|{{#if:{{{image_s15|}}}|{{{image_s15}}}}}}} [[{{{s15}}}]] }} }}</td> </tr> </table> }} |стиль_текста72 = text-align:left; |текст73 = {{{прим|}}} |стиль_текста73 = border-top:1px solid #a2a9b1; color:#54595d; padding-top:0.5em; text-align:left; |внизу = {{карточка/Викисклад|{{{викисклад|}}}|from={{{from|}}}}} }}{{#if:{{NAMESPACE}}{{{nocat|}}}||<!-- -->{{категория по дате|{{{образовано|}}}|Государства и территории, основанные|p571|from={{{from|}}}}}<!-- -->{{категория по дате|{{{образовано2|}}}|Государства и территории, основанные|from={{{from|}}}}}<!-- -->{{категория по дате|{{{образовано3|}}}|Государства и территории, основанные|from={{{from|}}}}}<!-- -->{{категория по дате|{{{ликвидировано|}}}|Государства и территории, исчезнувшие|p576|from={{{from|}}}}}<!-- -->{{категория по дате|{{{ликвидировано2|}}}|Государства и территории, исчезнувшие|from={{{from|}}}}}<!-- -->{{категория по дате|{{{ликвидировано3|}}}|Государства и территории, исчезнувшие|from={{{from|}}}}}<!-- -->{{#ifeq:{{{флаг}}}|novalue|{{#if:{{wikidata|p41|from={{{from|}}}}}|[[Категория:Статьи со спорным параметром в Викиданных]]}}|}}{{#ifeq:{{{герб}}}|novalue|{{#if:{{if-wikidata|p94|from={{{from|}}}}}|[[Категория:Статьи со спорным параметром в Викиданных]]}}|}}<!-- -->}}<noinclude>{{doc}}</noinclude> 3f810e404f545118ca6d15a13a0a04829c1f3c88 Модуль:Category handler 828 31 415 49 2024-08-10T16:55:58Z DuOfOrl 5 1 версия импортирована Scribunto text/plain -------------------------------------------------------------------------------- -- -- -- CATEGORY HANDLER -- -- -- -- This module implements the {{category handler}} template in Lua, -- -- with a few improvements: all namespaces and all namespace aliases -- -- are supported, and namespace names are detected automatically for -- -- the local wiki. This module requires [[Module:Namespace detect]] -- -- and [[Module:Yesno]] to be available on the local wiki. It can be -- -- configured for different wikis by altering the values in -- -- [[Module:Category handler/config]], and pages can be blacklisted -- -- from categorisation by using [[Module:Category handler/blacklist]]. -- -- -- -------------------------------------------------------------------------------- -- Load required modules local yesno = require('Module:Yesno') -- Lazily load things we don't always need local mShared, mappings local p = {} -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function trimWhitespace(s, removeBlanks) if type(s) ~= 'string' then return s end s = s:match('^%s*(.-)%s*$') if removeBlanks then if s ~= '' then return s else return nil end else return s end end -------------------------------------------------------------------------------- -- CategoryHandler class -------------------------------------------------------------------------------- local CategoryHandler = {} CategoryHandler.__index = CategoryHandler function CategoryHandler.new(data, args) local obj = setmetatable({ _data = data, _args = args }, CategoryHandler) -- Set the title object do local pagename = obj:parameter('demopage') local success, titleObj if pagename then success, titleObj = pcall(mw.title.new, pagename) end if success and titleObj then obj.title = titleObj if titleObj == mw.title.getCurrentTitle() then obj._usesCurrentTitle = true end else obj.title = mw.title.getCurrentTitle() obj._usesCurrentTitle = true end end -- Set suppression parameter values for _, key in ipairs{'nocat', 'categories'} do local value = obj:parameter(key) value = trimWhitespace(value, true) obj['_' .. key] = yesno(value) end do local subpage = obj:parameter('subpage') local category2 = obj:parameter('category2') if type(subpage) == 'string' then subpage = mw.ustring.lower(subpage) end if type(category2) == 'string' then subpage = mw.ustring.lower(category2) end obj._subpage = trimWhitespace(subpage, true) obj._category2 = trimWhitespace(category2) -- don't remove blank values end return obj end function CategoryHandler:parameter(key) local parameterNames = self._data.parameters[key] local pntype = type(parameterNames) if pntype == 'string' or pntype == 'number' then return self._args[parameterNames] elseif pntype == 'table' then for _, name in ipairs(parameterNames) do local value = self._args[name] if value ~= nil then return value end end return nil else error(string.format( 'invalid config key "%s"', tostring(key) ), 2) end end function CategoryHandler:isSuppressedByArguments() return -- See if a category suppression argument has been set. self._nocat == true or self._categories == false or ( self._category2 and self._category2 ~= self._data.category2Yes and self._category2 ~= self._data.category2Negative ) -- Check whether we are on a subpage, and see if categories are -- suppressed based on our subpage status. or self._subpage == self._data.subpageNo and self.title.isSubpage or self._subpage == self._data.subpageOnly and not self.title.isSubpage end function CategoryHandler:shouldSkipBlacklistCheck() -- Check whether the category suppression arguments indicate we -- should skip the blacklist check. return self._nocat == false or self._categories == true or self._category2 == self._data.category2Yes end function CategoryHandler:matchesBlacklist() if self._usesCurrentTitle then return self._data.currentTitleMatchesBlacklist else mShared = mShared or require('Module:Category handler/shared') return mShared.matchesBlacklist( self.title.prefixedText, mw.loadData('Module:Category handler/blacklist') ) end end function CategoryHandler:isSuppressed() -- Find if categories are suppressed by either the arguments or by -- matching the blacklist. return self:isSuppressedByArguments() or not self:shouldSkipBlacklistCheck() and self:matchesBlacklist() end function CategoryHandler:getNamespaceParameters() if self._usesCurrentTitle then return self._data.currentTitleNamespaceParameters else if not mappings then mShared = mShared or require('Module:Category handler/shared') mappings = mShared.getParamMappings(true) -- gets mappings with mw.loadData end return mShared.getNamespaceParameters( self.title, mappings ) end end function CategoryHandler:namespaceParametersExist() -- Find whether any namespace parameters have been specified. -- We use the order "all" --> namespace params --> "other" as this is what -- the old template did. if self:parameter('all') then return true end if not mappings then mShared = mShared or require('Module:Category handler/shared') mappings = mShared.getParamMappings(true) -- gets mappings with mw.loadData end for ns, params in pairs(mappings) do for i, param in ipairs(params) do if self._args[param] then return true end end end if self:parameter('other') then return true end return false end function CategoryHandler:getCategories() local params = self:getNamespaceParameters() local nsCategory for i, param in ipairs(params) do local value = self._args[param] if value ~= nil then nsCategory = value break end end if nsCategory ~= nil or self:namespaceParametersExist() then -- Namespace parameters exist - advanced usage. if nsCategory == nil then nsCategory = self:parameter('other') end local ret = {self:parameter('all')} local numParam = tonumber(nsCategory) if numParam and numParam >= 1 and math.floor(numParam) == numParam then -- nsCategory is an integer ret[#ret + 1] = self._args[numParam] else ret[#ret + 1] = nsCategory end if #ret < 1 then return nil else return table.concat(ret) end elseif self._data.defaultNamespaces[self.title.namespace] then -- Namespace parameters don't exist, simple usage. return self._args[1] end return nil end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- Used for testing purposes. return { CategoryHandler = CategoryHandler } end function p._main(args, data) data = data or mw.loadData('Module:Category handler/data') local handler = CategoryHandler.new(data, args) if handler:isSuppressed() then return nil end return handler:getCategories() end function p.main(frame, data) data = data or mw.loadData('Module:Category handler/data') local args = require('Module:Arguments').getArgs(frame, { wrappers = data.wrappers, valueFunc = function (k, v) v = trimWhitespace(v) if type(k) == 'number' then if v ~= '' then return v else return nil end else return v end end }) return p._main(args, data) end return p b74dd63857b24904ac452429b11213f18647471f Модуль:Wikidata/number 828 186 417 416 2024-08-10T16:56:04Z DuOfOrl 5 1 версия импортирована Scribunto text/plain local p = {} function p.formatVisualMagnitude ( context, options ) if ( not context ) then error( 'context not specified' ); end; if ( not options ) then error( 'options not specified' ); end; min = context.selectClaims( options, 'P1215[P1227:Q76596947][rank:normal,rank:preferred]' ) max = context.selectClaims( options, 'P1215[P1227:Q76596417][rank:normal,rank:preferred]' ) if ( not min or not max) then -- показываем как обычно return context.formatPropertyDefault( context, options ) end -- показываем Vmin-Vmax для переменной звезды local lang = mw.language.getContentLanguage(); for _, claim1 in ipairs(min) do for _, claim2 in ipairs(max) do return lang:formatNum(tonumber(claim1.mainsnak.datavalue.value.amount)) .. ' − ' .. lang:formatNum(tonumber(claim2.mainsnak.datavalue.value.amount)) end end end function p.formatColorIndex( context, options ) if ( not context ) then error( 'context not specified' ); end; if ( not options ) then error( 'options not specified' ); end; if ( options.property ) then -- Пролучаем все claims независимо от ранга claims = context.selectClaims( options, options.property .. '[rank:normal,rank:preferred]' ); end if ( claims ) then return context.formatPropertyDefault( context, options ) end -- Вычисляем B-V либо U-B из P1215 b = context.selectClaims( options, 'P1215[P1227:Q6746395][rank:normal,rank:preferred]' ) if ( not b ) then return end if string.find( options.property, 'Q17773035' ) then m1 = context.selectClaims( options, 'P1215[P1227:Q15977921][rank:normal,rank:preferred]' ) m2 = b if ( not m1 ) then return end else m1 = b m2 = context.selectClaims( options, 'P1215[P1227:Q4892529][rank:normal,rank:preferred]' ) if ( not m2 ) then return end end for _, claim1 in ipairs(m1) do for _, claim2 in ipairs(m2) do newClaim = { mainsnak = { snaktype = 'value', datavalue = { type = 'quantity', value = { unit = '1', amount = claim1.mainsnak.datavalue.value.amount - claim2.mainsnak.datavalue.value.amount }}}} return context.formatStatementDefault( context, options, newClaim ) end end end function p.formatPropertyWithMostRecentClaimAndIndicator( context, options ) if ( not context ) then error( 'context not specified' ); end; if ( not options ) then error( 'options not specified' ); end; if ( not options.entity ) then error( 'options.entity missing' ); end; local claims; if options.property then -- Пролучаем все claims независимо от ранга claims = context.selectClaims( options, options.property .. '[rank:normal,rank:preferred]' ); end if claims == nil then return '' end -- Ищем claim с максимальным значением P585 и форматируем его в out local maxTimestamp = nil; local mostRecentClaim; for i, claim in ipairs(claims) do if (claim.qualifiers and claim.qualifiers.P585) then -- обрабатываем только claims с указанным P585 local timestamp = context.parseTimeFromSnak( claim.qualifiers.P585[1] ); if timestamp ~= nil and ( maxTimestamp == nil or maxTimestamp < timestamp ) then maxTimestamp = timestamp; mostRecentClaim = claim end end end if (not mostRecentClaim) then -- нет ни одного claim с указанным P585 return context.formatPropertyDefault( context, options ) end local out = context.formatStatement( options, mostRecentClaim ) if out ~= '' then -- Ищем claim со значением P585 сразу после максимального и запоминаем его в secondMostRecentValue local secondMostRecentTimestamp = 0; local secondMostRecentValue = 0; for i, claim in ipairs(claims) do if (claim.qualifiers and claim.qualifiers.P585) then -- обрабатываем только claims с указанным P585 local timestamp = context.parseTimeFromSnak( claim.qualifiers.P585[1] ) if (timestamp ~= nil and secondMostRecentTimestamp < timestamp and maxTimestamp > timestamp) then secondMostRecentTimestamp = timestamp secondMostRecentValue = tonumber( claim.mainsnak.datavalue.value.amount ) end end end if (secondMostRecentValue ~= 0) then -- если предыдущее значение нашлось if (secondMostRecentValue < tonumber( mostRecentClaim.mainsnak.datavalue.value.amount )) then out = '<span style="color: #0c0; font-size: larger;">▲</span>' .. out else out = '<span style="color: red; font-size: larger;">▼</span>' .. out end end if options.before then out = options.before .. out end if options.after then out = out .. options.after end end return out end function p.formatQuantityWithDateClaim( context, options, statement ) local snak = context.formatSnak( options, statement.mainsnak ) if not snak then return '' end --Date if ( statement.qualifiers and statement.qualifiers.P585 ) then snak = snak .. ' (' .. context.formatSnak( options, statement.qualifiers.P585[1] ) .. ')' end --References if ( options.references ) then snak = snak .. context.formatRefs( options, statement ); end return snak end function p.formatDMS( context, options, value ) if not value.amount then return value end if options and options.unit == '-' then return value.amount end local prefix = "+" if tonumber( value.amount ) < 0 then prefix = "−" end return p.formatAngle ( math.abs( tonumber( value.amount ) ), string.len( value.amount ) - string.find( value.amount, '.', 1, true ) - 5, prefix .. "%s° %02d′ %s″") end function p.formatRA( context, options, value ) if not value.amount then return value end if options and options.unit == '-' then return value.amount end return p.formatAngle (tonumber( value.amount ) / 15, string.len( value.amount ) - string.find( value.amount, '.', 1, true ) - 4, "%s<sup>ч</sup> %02d<sup>м</sup> %s<sup>с</sup>") end function p.formatAngle ( angle, sig, format ) local d, angle = math.modf( angle ) local m, angle = math.modf( angle * 60 ) local mult = 10 ^ sig; local s = math.floor( angle * 60 * mult + 0.5 ) / mult; local lang = mw.language.getContentLanguage(); return string.format( format, d, m, lang:formatNum( s ) ) end return p 2f96549583b299597b7f95fbceeddad31ccee753 Шаблон:No-doc 10 187 419 418 2024-08-10T16:56:06Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{#ifeq: {{SUBPAGENAME}} | doc || {{#if: {{#if: {{yesno|{{{nocat|}}}}} | x }}{{#switch: {{NAMESPACE}} | {{ns:10}} | {{ns:828}} = | x }} || {{{1|}}} }} }}<noinclude>{{doc}}</noinclude> da013ca5b5f97f94bee392ff3a4488046f2ceac7 Шаблон:Clear 10 188 421 420 2024-08-10T16:56:09Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <div style="clear:{{{1|both}}};"></div><noinclude>{{doc}}</noinclude> 15e943687be5d8f8e27fa6cc7813bbfa85df72a9 Шаблон:- 10 189 423 422 2024-08-10T16:56:10Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki #перенаправление [[Шаблон:Clear]] f3ec5262c8fab1ae984101008632fb9c091fb431 Шаблон:Ombox 10 20 425 38 2024-08-10T16:56:11Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{#invoke:Message box|ombox}}<noinclude> {{doc}}<!-- Add categories and interwikis to the /doc subpage, not here! --></noinclude> ab34435c5ebc29de589c9b059e88da5d0e6f16e4 Шаблон:Переписать шаблон 10 190 427 426 2024-08-10T16:56:12Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{ombox |type = style |text = '''Этот шаблон следует переписать{{#if: {{{меташаблон|}}} | &nbsp;с использованием меташаблона {{tl|{{{меташаблон}}}}} }}.''' <div style="font-size:95%;">{{#if: {{{меташаблон|}}} | Использование меташаблонов позволяет более полно использовать возможности шаблонов (см. [[Википедия:Рекомендации по созданию шаблонов]])|См. также [[Википедия:Рекомендации по созданию шаблонов]].}}</div> }}<includeonly>{{no-doc|nocat={{{nocat|}}}|{{#switch: {{lc: {{{меташаблон|}}} }} | карточка = [[Категория:Википедия:Шаблоны для перевода на карточку]] | навигационная таблица = [[Категория:Википедия:Шаблоны для перевода на навигационную таблицу]] | статья проекта = [[Категория:Википедия:Шаблоны для перевода на статью проекта]] | ае | административная единица = [[Категория:Википедия:Шаблоны для перевода на шаблон АЕ]] | [[Категория:Википедия:Шаблоны к переработке]] }} {{#switch: {{lc: {{{меташаблон|}}} }} | карточка | карточка персонажа | ае | административная единица | воинское формирование ссср | карточка/блок = [[Категория:Шаблоны-карточки по алфавиту]] }} }}</includeonly><noinclude>{{doc}}</noinclude> cb8733e779fa70731f445053204e92dc5afa0ebb Шаблон:Историческое государство/doc 10 191 429 428 2024-08-10T16:56:12Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{docpage}} {{Переписать шаблон|меташаблон=Карточка/блок с маркерами}} Этот [[Википедия:Шаблоны-карточки|шаблон-карточка]] используется для вставки карточки в статьи об отдельных исторических государствах. * для современных государств используется {{t|государство}}. * для составных частей государств используется {{t|административная единица}}. == Заготовка, включающая все возможные параметры == <pre> {{Историческое государство |название = |самоназвание = |статус = |гимн = |флаг = |описание_флага = |герб = |описание_герба = |карта = |размер = |описание = <!-- |type_before = если этот параметр присутствует в шаблоне, то необходимо указать примерно следующее: «Государства-основатели», иначе удалите его, автоматически будет указано: «Предшественники».--> |p1 = |flag_p1 = |image_p1 = |p2 = |flag_p2 = |image_p2 = |p3 = |flag_p3 = |image_p3 = |p4 = |flag_p4 = |image_p4 = |образовано = |ликвидировано = <!-- |type_after = если этот параметр присутствует в шаблоне, то необходимо указать примерно следующее: «Государства после распада…», иначе удалите его, автоматически будет указано: «Преемники».--> |s1 = |flag_s1 = |image_s1 = |s2 = |flag_s2 = |image_s2 = |s3 = |flag_s3 = |image_s3 = |s4 = |flag_s4 = |image_s4 = |девиз = |столица = |города = |язык = |валюта = |дополнительный_параметр = |содержимое_параметра = |площадь = |население = |форма_правления = |династия = |титул_правителей = |правитель1 = <!--Не вставляйте в шаблон всех правителей, если их много — он не для этого! Создайте соответствующий раздел в статье. --> |год_правителя1 = |титул_правителей2 = <!--используется при изменении титула последующего правителя--> |правитель2 = |год_правителя2 = |титул_правителей3 = |правитель3 = |год_правителя3 = |титул_правителей4 = |правитель4 = |год_правителя4 = |титул_правителей5 = |правитель5 = |год_правителя5 = |титул_правителей6 = |правитель6 = |год_правителя6 = |религия = |дополнительный_параметр1 = |содержимое_параметра1 = |Этап1 = |Дата1 = |Год1 = |Этап2 = |Дата2 = |Год2 = |Этап3 = |Дата3 = |Год3 = |Этап4 = |Дата4 = |Год4 = |Этап5 = |Дата5 = |Год5 = |Этап6 = |Дата6 = |Год6 = |Этап7 = |Дата7 = |Год7 = |Этап8 = |Дата8 = |Год8 = |Этап9 = |Дата9 = |Год9 = |Этап10 = |Дата10 = |Год10 = |Этап11 = |Дата11 = |Год11 = |дополнительный_параметр2 = |содержимое_параметра2 = |до = |д1 = |д2 = |д3 = |д4 = |д5 = |д6 = |д7 = |после = |п1 = |п2 = |п3 = |п4 = |п5 = |п6 = |п7 = |прим = |викисклад = }} </pre> * ''Название'' — официальное наименование административной единицы (если административная единица имела несколько официальных наименований — указывается то, что применялось на протяжении наибольшего времени существования территории). * ''Самоназвание'' — название на официальном языке административной единицы. * ''Статус'' — административный статус единицы (царство, княжество, королевство и т. д.). * ''Гимн'' — гимн территории. Параметр поддерживает импорт викиданных. * ''Флаг'' — флаг территории. Параметр поддерживает импорт викиданных. Есть возможность [[ВП:ЛЖЕГЕРБ|выключить]], заполнив параметр текстом <code>novalue</code>. Для полного выключения полосы надо так же заполнить параметр ''Герб''. * ''описание_флага'' — Если не задано, по умолчанию отображается подпись Флаг. Подпись особенно полезна, если государство в разное время имело разл. флаги. * ''Герб'' — герб территории. Параметр поддерживает импорт викиданных. Есть возможность [[ВП:ЛЖЕГЕРБ|выключить]], заполнив параметр текстом <code>novalue</code>. Для полного выключения полосы надо так же заполнить параметр ''Флаг''. * ''описание_герба'' — Если не задано, по умолчанию отображается подпись Герб. Подпись особенно полезна, если государство в разное время имело разл. гербы. * ''Карта'' — карта территории, желательно, по наиболее позднему состоянию. Параметр поддерживает импорт викиданных. * ''размер'' — необязательное поле, по умолчанию = 270px * ''Описание'' — описание карты, заметки. * ''Девиз'' — девиз правящего дома либо государства. * ''type_before'' — если этот параметр присутствует в шаблоне, то необходимо указать примерно следующее: «Государства-основатели», иначе удалите его, автоматически будет указано: «Предшественники». * ''p1'' — название административной единицы, существовавшей на данной территории до создания предмета статьи (станет ссылкой). * ''flag_p1'' — флаг административной единицы, существовавшей на данной территории до создания предмета статьи. * ''image_pN '' — гербы и другие изображения, для которых нежелательна рамка (в формате <nowiki>[[File:...|Npx]]</nowiki>) * ''s1'' — название административной единицы, существовавшей на данной территории после упразднения предмета статьи (станет ссылкой). * ''flag_s1'' — флаг административной единицы, существовавшей на данной территории после упразднения предмета статьи. * ''image_sN '' — гербы и другие изображения, для которых нежелательна рамка (в формате <nowiki>[[File:...|Npx]]</nowiki>) * ''pN'' — другие предшественники (если более четырёх, используйте параметры «До» и «После»). * ''flag_sN'' — флаги государств-предшественников. * ''Образовано'' — год образования административной единицы. Параметр поддерживает импорт викиданных. * ''ликвидировано'' — год прекращения существования административной единицы. Параметр поддерживает импорт викиданных. * ''type_after'' — если этот параметр присутствует в шаблоне, то необходимо указать примерно следующее: «Государства после распада…», иначе удалите его, автоматически будет указано: «Преемники». * ''pN'' — другие преемники (если более четырёх, используйте параметры «До» и «После»). * ''flag_pN'' — флаги государств-преемников. * ''Столица'' — административный центр территории. Параметр поддерживает импорт викиданных. * ''Валюта'' — денежная единица данной территории. Параметр поддерживает импорт викиданных. * ''Города'' — крупнейшие города данной территории. * ''Язык'' — официальный язык территории. Параметр поддерживает импорт викиданных. * ''Форма_правления'' — форма правления на данной территории. Параметр поддерживает импорт викиданных. * ''титул_правителей'' — титулы правителей, заданных в параметрах правитель N. Например: «Короли». Если правители имели различные титулы, можно воспользоваться более общей формулировкой, например: «Основные правители». * ''титул_правителейN'' — используется при изменении титула последующего правителя. * ''правительN'' — имя правителя N * ''год_правителяN'' — годы правления правителя N * ''Дополнительный_параметр1, 2'' — название параметра. * ''Содержимое_параметра1, 2'' — содержимое параметра. * ''ЭтапN'' — название этапа в истории государства (до 11). * ''ДатаN'' — дата начала этапа (до 11). * ''ГодN'' — год начала этапа (до 11). * ''До'' — название административной единицы, существовавшей на данной территории до создания предмета статьи. * ''После'' — название административной единицы, существовавшей на данной территории после упразднения предмета статьи. * ''дN'' — другие предшественники (до 7). * ''пN'' — другие преемники (до 7). * ''прим'' — примечания. * ''викисклад'' — категория на Викискладе. <includeonly> [[Категория:Шаблоны-карточки:Географические объекты]] [[Категория:Шаблоны-карточки:История]] </includeonly> 56637e0862b3c305ebd1643f0787f74a89bf78cf Шаблон:Ambox 10 193 433 432 2024-08-10T17:14:58Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{#invoke:Message box|ambox}}{{#ifeq:{{{small}}}|left|[[Категория:Страницы, использующие малые шаблоны-сообщения]]}}<noinclude> {{doc}} <!-- Categories go on the /doc subpage, and interwikis go on Wikidata. --> </noinclude> 5345bd7c0e2430e3672a54d920abd0f0bf61dc61 Шаблон:TOC right 10 194 435 434 2024-08-10T17:15:04Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <templatestyles src="Шаблон:TOC right/styles.css" /><!-- -->{{#if: {{{limit|}}} | <templatestyles src="Шаблон:TOC limit/styles.css" /> }}<!-- --><div class="ts-TOC_right {{#if: {{{limit|}}} | ts-TOC_limit-{{{limit|}}} }}" style="{{#if: {{{clear|}}} | clear:{{{clear|}}}; }}{{#if: {{{width|{{{1|}}}}}} | width:{{{width|{{{1|}}}}}}; }}{{#if: {{{max-width|}}} | max-width: {{{max-width|}}}; }}">__TOC__</div><noinclude> {{doc}} </noinclude> 84311f23c6ae2f952b4496c710868089ed317e45 Шаблон:TOC right/styles.css 10 195 437 436 2024-08-10T17:15:05Z DuOfOrl 5 1 версия импортирована sanitized-css text/css @media (min-width: 720px) { body:not(.skin-minerva) .ts-TOC_right { margin-left: 1em; margin-bottom: 0.5em; float: right; clear: right; } } @media (max-width: 719px) { .ts-TOC_right { width: auto !important; max-width: none !important; clear: none !important; } } body.skin-vector-2022 .ts-TOC_right { display: none; } /* [[Категория:Шаблоны:Подстраницы CSS]] */ 710a99f2d4d2a78eb7a6f884538055bb6ac67c99 Шаблон:Начало скрытого блока 10 196 439 438 2024-08-10T17:15:06Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <includeonly><templatestyles src="Шаблон:Скрытый блок/styles.css" /><!-- --><div class="mw-collapsible {{#switch: {{{состояние|{{{state|}}}}}} | expanded | autocollapse = {{{состояние|{{{state|}}}}}} | mw-collapsed }} ts-Скрытый_блок ts-Скрытый_блок-{{#switch: {{{тип|{{{type|}}}}}} | gray | transparent = {{{тип|{{{type|}}}}}} | gray }} ts-Скрытый_блок-{{#switch: {{{Ссылка|{{{ссылка|}}}}}} | none = none | right | left = {{{Ссылка|{{{ссылка|}}}}}} | right }}HideLink {{{класс_тела|{{{класс тела|}}}}}}" style="{{ifempty |до = border: | {{{Рамка|{{{border|{{{рамка|}}}}}}}}} |после=;}}{{{frame-style|{{{стиль_тела|{{{стиль тела|}}}}}}}}}"><!-- --><div class="ts-Скрытый_блок-title {{#switch: {{{Выравнивание_заголовка|{{{ta1|{{{выравнивание_заголовка|{{{выравнивание заголовка|}}}}}}}}}}}} | none = none | left | right = ts-Скрытый_блок-title-{{{Выравнивание_заголовка|{{{ta1|{{{выравнивание_заголовка|{{{выравнивание заголовка|}}}}}}}}}}}}Title }} {{{класс_заголовка|{{{класс заголовка|}}}}}}" style="<!-- -->{{ifempty |до = background-color: | {{{Фон_заголовка|{{{bg1|{{{фон_заголовка|{{{фон заголовка|}}}}}}}}}}}} |после=;}}<!-- -->{{ifempty |до = text-align: | {{{Выравнивание_заголовка|{{{ta1|{{{выравнивание_заголовка|{{{выравнивание заголовка|}}}}}}}}}}}} |после=;}}<!-- -->{{ifempty |до = font-weight: | {{{Шрифт_заголовка|{{{шрифт_заголовка|{{{шрифт заголовка|}}}}}}}}} |после=;}}<!-- -->{{ifempty |до = font-style: | {{{Наклон_заголовка|{{{наклон_заголовка|{{{наклон заголовка|}}}}}}}}} |после=;}}<!-- -->{{{Стиль_заголовка|{{{extra1|{{{стиль_заголовка|{{{стиль заголовка|}}}}}}}}}}}}"><!-- -->{{{Заголовок|{{{заголовок|{{{Заглавие|{{{заглавие|{{{Название|{{{название|{{{header|{{{title|{{{1}}}}}}}}}}}}}}}}}}}}}}}}}}}<!-- --><div class="mw-collapsible-toggle-placeholder"></div></div><!-- --><div class="mw-collapsible-content {{{класс_текста|{{{класс текста|}}}}}}" style="<!-- -->{{ifempty |до = background-color: | {{{Фон_текста|{{{bg2|{{{фон_текста|{{{фон текста|}}}}}}}}}}}} |после=;}}<!-- -->{{ifempty |до = font-weight: | {{{Шрифт_текста|{{{шрифт_текста|{{{шрифт текста|}}}}}}}}} |после=;}}<!-- -->{{ifempty |до = font-style: | {{{Наклон_текста|{{{наклон_текста|{{{наклон текста|}}}}}}}}} |после=;}}<!-- -->{{ifempty |до = text-align: | {{{Выравнивание_текста|{{{ta2|{{{выравнивание_текста|{{{выравнивание текста|}}}}}}}}}}}} |после=;}}<!-- -->{{{Стиль_текста|{{{extra2|{{{стиль_текста|{{{стиль текста|}}}}}}}}}}}}"><!-- --></includeonly><noinclude> {{doc}} </noinclude> 3b96bb802b522e629c41cddc5d44dfb2a9eb462a Шаблон:Скрытый блок/styles.css 10 197 441 440 2024-08-10T17:15:07Z DuOfOrl 5 1 версия импортирована sanitized-css text/css .ts-Скрытый_блок { margin: 0; overflow: hidden; border-collapse: collapse; box-sizing: border-box; font-size: 95%; } .ts-Скрытый_блок-title { text-align: center; font-weight: bold; line-height: 1.6em; min-height: 1.2em; } .ts-Скрытый_блок .mw-collapsible-content { overflow-x: auto; overflow-y: hidden; clear: both; } .ts-Скрытый_блок::before, .ts-Скрытый_блок .mw-collapsible-toggle { padding-top: .1em; width: 6em; font-weight: normal; font-size: calc(90% / 0.95); } .ts-Скрытый_блок-rightHideLink .mw-collapsible-toggle { float: right; text-align: right; } .ts-Скрытый_блок-leftHideLink .mw-collapsible-toggle { float: left; text-align: left; } .ts-Скрытый_блок-gray { padding: 2px; border: 1px solid var(--border-color-base, #a2a9b1); } .ts-Скрытый_блок-transparent { border: none; } .ts-Скрытый_блок-gray .ts-Скрытый_блок-title { background: var(--background-color-neutral, #eaecf0); padding: .1em 6em; padding-right: 0; } .ts-Скрытый_блок-transparent .ts-Скрытый_блок-title { background: transparent; padding: .1em 5.5em; padding-right: 0; } .ts-Скрытый_блок-gray .mw-collapsible-content { padding: .25em 1em; } .ts-Скрытый_блок-transparent .mw-collapsible-content { padding: .25em 0; } .ts-Скрытый_блок-gray.ts-Скрытый_блок-rightHideLink .mw-collapsible-toggle { padding-right: 1em; } .ts-Скрытый_блок-transparent.ts-Скрытый_блок-rightHideLink .mw-collapsible-toggle { padding-right: 0; } .ts-Скрытый_блок-gray.ts-Скрытый_блок-leftHideLink .mw-collapsible-toggle { padding-left: 1em; } .ts-Скрытый_блок-transparent.ts-Скрытый_блок-leftHideLink .mw-collapsible-toggle { padding-left: 0; } .ts-Скрытый_блок-gray.ts-Скрытый_блок-rightHideLink .ts-Скрытый_блок-title-leftTitle { padding-left: 1em; } .ts-Скрытый_блок-gray.ts-Скрытый_блок-leftHideLink .ts-Скрытый_блок-title-leftTitle { padding-left: 6.5em; } .ts-Скрытый_блок-gray.ts-Скрытый_блок-leftHideLink .ts-Скрытый_блок-title-rightTitle { padding-right: 1em; } .ts-Скрытый_блок-transparent.ts-Скрытый_блок-rightHideLink .ts-Скрытый_блок-title-rightTitle, .ts-Скрытый_блок-transparent.ts-Скрытый_блок-rightHideLink .ts-Скрытый_блок-title-leftTitle { padding-left: 0; } .ts-Скрытый_блок-transparent.ts-Скрытый_блок-leftHideLink .ts-Скрытый_блок-title-rightTitle, .ts-Скрытый_блок-transparent.ts-Скрытый_блок-leftHideLink .ts-Скрытый_блок-title-leftTitle { padding-right: 0; } .ts-Скрытый_блок + .ts-Скрытый_блок, .ts-Скрытый_блок + link + .ts-Скрытый_блок { border-top-style: hidden; } /* [[Категория:Шаблоны:Подстраницы CSS]] */ 41e605b205f412804b46a4c6c5dd51a71c6a59ca Шаблон:Ifempty 10 198 443 442 2024-08-10T17:15:07Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <includeonly>{{#invoke:Ifempty|main}}</includeonly><noinclude> {{Doc}} <!-- Add categories and interwikis to the /doc subpage, not here! Добавляйте категории и интервики на подстраницу документации, а не сюда --> </noinclude> c14bef2160201468f96da309e565ff2fde725cf5 Шаблон:Конец скрытого блока 10 199 445 444 2024-08-10T17:15:08Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <includeonly></div></div></includeonly><noinclude> {{doc|Шаблон:Начало скрытого блока/doc}}</noinclude> 2da6ac8eb0812fb4183a70b516009d40920e281f Шаблон:Скрытый блок 10 200 447 446 2024-08-10T17:15:10Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{Начало скрытого блока |id = {{{id|}}} |тип = {{{тип|{{{type|}}}}}} |состояние = {{{state|{{{состояние|collapsed}}}}}} |класс_тела = {{{класс_тела|{{{класс тела|}}}}}} |стиль_тела = {{{frame-style|{{{стиль_тела|{{{стиль тела|}}}}}}}}} |рамка = {{{Рамка|{{{border|{{{рамка|}}}}}}}}} |заголовок = {{{Заголовок|{{{заголовок|{{{Заглавие|{{{заглавие|{{{Название|{{{название|{{{header|{{{title|{{{1}}}}}}}}}}}}}}}}}}}}}}}}}}} |ссылка = {{{Ссылка|{{{ссылка|}}}}}} |класс_заголовка = {{{класс_заголовка|{{{класс заголовка|}}}}}} |шрифт_заголовка = {{{Шрифт_заголовка|{{{шрифт_заголовка|{{{шрифт заголовка|}}}}}}}}} |наклон_заголовка = {{{Наклон_заголовка|{{{наклон_заголовка|{{{наклон заголовка|}}}}}}}}} |фон_заголовка = {{{Фон_заголовка|{{{bg1|{{{фон_заголовка|{{{фон заголовка|}}}}}}}}}}}} |выравнивание_заголовка = {{{Выравнивание_заголовка|{{{ta1|{{{выравнивание_заголовка|{{{выравнивание заголовка|}}}}}}}}}}}} |стиль_заголовка = {{{title-style|{{{Стиль_заголовка|{{{extra1|{{{стиль_заголовка|{{{стиль заголовка|}}}}}}}}}}}}}}} |класс_текста = {{{класс_текста|{{{класс текста|}}}}}} |шрифт_текста = {{{Шрифт_текста|{{{шрифт_текста|{{{шрифт текста|}}}}}}}}} |наклон_текста = {{{Наклон_текста|{{{наклон_текста|{{{наклон текста|}}}}}}}}} |фон_текста = {{{Фон_текста|{{{bg2|{{{фон_текста|{{{фон текста|}}}}}}}}}}}} |выравнивание_текста = {{{Выравнивание_текста|{{{ta2|{{{выравнивание_текста|{{{выравнивание текста|}}}}}}}}}}}} |стиль_текста = {{{content-style|{{{Стиль_текста|{{{extra2|{{{стиль_текста|{{{стиль текста|}}}}}}}}}}}}}}}}} {{{content|{{{Содержание|{{{содержание|{{{2}}}}}}}}}}}} {{#if: {{{footer|}}} | <div style="{{{footer-style|{{{title-style|}}}}}}">{{{footer}}}</div> }} {{Конец скрытого блока}}<noinclude> {{doc}} </noinclude> 792dc9fb2eb659877e2e758f4ce405e1d3f8352b Шаблон:Заготовка раздела 10 201 449 448 2024-08-10T17:15:11Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{ {{{|safesubst:}}}#invoke:Unsubst||дата=__DATE__|$format=Y-m-d|$B= <!--{{Заготовка раздела}} begin-->{{ambox | name = Заготовка раздела | subst = <includeonly>{{subst:substcheck}}</includeonly> | type = content |image = [[Файл:Wiki letter w.svg|25px|link=|alt=]] | issue = Этот раздел '''[[Википедия:Заготовка статьи|не завершён]]'''. | talk = {{{talk|{{{обс|}}}}}} | fix = Вы поможете проекту, [[Википедия:Правила и указания|исправив и дополнив]] его{{#if: {{{1|}}} | <nowiki /> следующей информацией: {{{1}}} }}.<br>{{{comment|{{{c|{{{комм|{{{ком|{{{комментарий|{{{к|{{{com|{{{comm|}}}}}}}}}}}}}}}}}}}}}}}} | date = {{{date|{{{дата|}}}}}} | all = Википедия:Статьи с незавершёнными разделами | all2 = Википедия:Статьи с шаблонами недостатков по алфавиту | nocat = {{{nocat|}}} }} }}<noinclude>{{doc}}</noinclude> 354fe71955c1f4efa21d425cae329d66f9b43ce6 Шаблон:Ok 10 202 451 450 2024-08-10T17:15:13Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki [[File:Yes check.svg|15px|link=|alt=✔]]<noinclude> <!--alt нужен чтобы скрин-ридеры читали в атрибуте alt "✓" как "отметка" и чтобы без загрузки картинок показывалось "✓". Без рамки "|мини" и с отключающим "|link=" подпись преобразовывается сайтом в два атрибута у img (alt и title), поэтому нужно сделать alt отдельно от title "File" вместо "Файл" немного уменьшает размер включений шаблонов.--> {{doc}} </noinclude> 43161c9f08276343b6f3c9223a73c712bd7db413 Шаблон:Скрытый 10 203 453 452 2024-08-10T17:15:13Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki #перенаправление [[Шаблон:Скрытый блок]] 97cc939c1c8ece875b2ec360f85980bd6f1bbed7 Шаблон:Module rating 10 94 455 160 2024-08-10T17:15:14Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki #REDIRECT [[Шаблон:Рейтинг модуля]] 4fffdbbfc33a362b03306003030f85ea1a516c19 Шаблон:Tick 10 204 457 456 2024-08-10T17:15:15Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki #перенаправление [[Шаблон:Ok]] f0887beb67bfbdc74fa97e8dd35f78474edfcefc Шаблон:Cross 10 205 459 458 2024-08-10T17:15:16Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki [[File:X mark.svg|{{{1|20}}}px|link=|alt=]]<span style="display:none">N</span><!--template:cross--><noinclude> {{documentation}} </noinclude> ed4b409e99cfe41368cc2f86462c7f46372ac8bb Модуль:UnitTests 828 206 461 460 2024-08-10T17:15:17Z DuOfOrl 5 1 версия импортирована Scribunto text/plain -- Модуль основан на коде модуля [[:en:Module:UnitTests|Module:UnitTests]] англоязычного раздела Википедии. -- UnitTester provides unit testing for other Lua scripts. For details see [[Wikipedia:Lua#Unit_testing]]. -- For user documentation see talk page. local UnitTester = {} local frame, tick, cross, should_highlight local result_table_header = '{|class="wikitable unit-tests-result"\n|+ %s\n' .. '! scope="col" | \n' .. '! scope="col" | Тест\n' .. '! scope="col" | Ожидаемое значение\n' .. '! scope="col" | Фактическое значение ' local result_table_live_sandbox_header = '{|class="wikitable unit-tests-result"\n|+ %s\n' .. '! scope="col" | \n' .. '! scope="col" | Тест\n' .. '! scope="col" | Фактическое значение\n' .. '! scope="col" | Песочница\n' .. '! scope="col" | Ожидаемое значение' local result_table = { n = 0 } local result_table_mt = { insert = function (self, ...) local n = self.n for i = 1, select('#', ...) do local val = select(i, ...) if val ~= nil then n = n + 1 self[n] = val end end self.n = n end, insert_format = function (self, ...) self:insert(string.format(...)) end, concat = table.concat } result_table_mt.__index = result_table_mt setmetatable(result_table, result_table_mt) local num_failures = 0 local num_runs = 0 local function first_difference(s1, s2) s1, s2 = tostring(s1), tostring(s2) if s1 == s2 then return '' end local max = math.min(#s1, #s2) for i = 1, max do if s1:sub(i,i) ~= s2:sub(i,i) then return i end end return max + 1 end local function return_varargs(...) return ... end function UnitTester:calculate_output(text, expected, actual, options) -- Set up some variables for throughout for ease num_runs = num_runs + 1 local options = options or {} -- Fix any stripmarkers if asked to do so to prevent incorrect fails local compared_expected = expected local compared_actual = actual if options.templatestyles then local pattern = '(\127[^\127]*UNIQ%-%-templatestyles%-)(%x+)(%-QINU[^\127]*\127)' local _, expected_stripmarker_id = compared_expected:match(pattern) -- when module rendering has templatestyles strip markers, use ID from expected to prevent false test fail if expected_stripmarker_id then compared_actual = compared_actual:gsub(pattern, '%1' .. expected_stripmarker_id .. '%3') -- replace actual id with expected id; ignore second capture in pattern compared_expected = compared_expected:gsub(pattern, '%1' .. expected_stripmarker_id .. '%3') -- account for other strip markers end end if options.stripmarker then local pattern = '(\127[^\127]*UNIQ%-%-%l+%-)(%x+)(%-%-?QINU[^\127]*\127)' local _, expected_stripmarker_id = compared_expected:match(pattern) if expected_stripmarker_id then compared_actual = compared_actual:gsub(pattern, '%1' .. expected_stripmarker_id .. '%3') compared_expected = compared_expected:gsub(pattern, '%1' .. expected_stripmarker_id .. '%3') end end -- Perform the comparison local success = compared_actual == compared_expected if not success then num_failures = num_failures + 1 end -- Sort the wikitext for displaying the results if options.combined then -- We need 2 rows available for the expected and actual columns -- Top one is parsed, bottom is unparsed local differs_at = self.differs_at and (' \n| rowspan=2|' .. first_difference(compared_expected, compared_actual)) or '' -- Local copies of tick/cross to allow for highlighting local highlight = (should_highlight and not success and 'style="background:#fc0;" ') or '' result_table:insert( -- Start output '| ', highlight, 'rowspan=2|', success and tick or cross, -- Tick/Cross (2 rows) ' \n| rowspan=2|', mw.text.nowiki(text), ' \n| ', -- Text used for the test (2 rows) expected, ' \n| ', actual, -- The parsed outputs (in the 1st row) differs_at, ' \n|-\n| ', -- Where any relevant difference was (2 rows) mw.text.nowiki(expected), ' \n| ', mw.text.nowiki(actual), -- The unparsed outputs (in the 2nd row) '\n|-\n' -- End output ) else -- Display normally with whichever option was preferred (nowiki/parsed) local differs_at = self.differs_at and (' \n| ' .. first_difference(compared_expected, compared_actual)) or '' local formatting = options.nowiki and mw.text.nowiki or return_varargs local highlight = (should_highlight and not success and 'style="background:#fc0;"|') or '' result_table:insert( -- Start output '| ', highlight, success and tick or cross, -- Tick/Cross ' \n| ', mw.text.nowiki(text), ' \n| ', -- Text used for the test formatting(expected), ' \n| ', formatting(actual), -- The formatted outputs differs_at, -- Where any relevant difference was '\n|-\n' -- End output ) end end function UnitTester:preprocess_equals(text, expected, options) local actual = frame:preprocess(text) self:calculate_output(text, expected, actual, options) end function UnitTester:preprocess_equals_many(prefix, suffix, cases, options) for _, case in ipairs(cases) do self:preprocess_equals(prefix .. case[1] .. suffix, case[2], options) end end function UnitTester:preprocess_equals_preprocess(text1, text2, options) local actual = frame:preprocess(text1) local expected = frame:preprocess(text2) self:calculate_output(text1, expected, actual, options) end function UnitTester:preprocess_equals_compare(live, sandbox, expected, options) local live_text = frame:preprocess(live) local sandbox_text = frame:preprocess(sandbox) local highlight_live = false local highlight_sandbox = false num_runs = num_runs + 1 if live_text == expected and sandbox_text == expected then result_table:insert('| ', tick) else result_table:insert('| ', cross) num_failures = num_failures + 1 if live_text ~= expected then highlight_live = true end if sandbox_text ~= expected then highlight_sandbox = true end end local formatting = (options and options.nowiki and mw.text.nowiki) or return_varargs local differs_at = self.differs_at and (' \n| ' .. first_difference(expected, live_text) or first_difference(expected, sandbox_text)) or '' result_table:insert( ' \n| ', mw.text.nowiki(live), should_highlight and highlight_live and ' \n|style="background: #fc0;"| ' or ' \n| ', formatting(live_text), should_highlight and highlight_sandbox and ' \n|style="background: #fc0;"| ' or ' \n| ', formatting(sandbox_text), ' \n| ', formatting(expected), differs_at, "\n|-\n" ) end function UnitTester:preprocess_equals_preprocess_many(prefix1, suffix1, prefix2, suffix2, cases, options) for _, case in ipairs(cases) do self:preprocess_equals_preprocess(prefix1 .. case[1] .. suffix1, prefix2 .. (case[2] and case[2] or case[1]) .. suffix2, options) end end function UnitTester:preprocess_equals_sandbox_many(module, function_name, cases, options) for _, case in ipairs(cases) do local live = module .. "|" .. function_name .. "|" .. case[1] .. "}}" local sandbox = module .. "/песочница|" .. function_name .. "|" .. case[1] .. "}}" self:preprocess_equals_compare(live, sandbox, case[2], options) end end function UnitTester:equals(name, actual, expected, options) num_runs = num_runs + 1 if actual == expected then result_table:insert('| ', tick) else result_table:insert('| ', cross) num_failures = num_failures + 1 end local formatting = (options and options.nowiki and mw.text.nowiki) or return_varargs local differs_at = self.differs_at and (' \n| ' .. first_difference(expected, actual)) or '' local display = options and options.display or return_varargs result_table:insert(' \n| ', name, ' \n| ', formatting(tostring(display(expected))), ' \n| ', formatting(tostring(display(actual))), differs_at, "\n|-\n") end local function deep_compare(t1, t2, ignore_mt) local ty1 = type(t1) local ty2 = type(t2) if ty1 ~= ty2 then return false end if ty1 ~= 'table' and ty2 ~= 'table' then return t1 == t2 end local mt = getmetatable(t1) if not ignore_mt and mt and mt.__eq then return t1 == t2 end for k1, v1 in pairs(t1) do local v2 = t2[k1] if v2 == nil or not deep_compare(v1, v2) then return false end end for k2, v2 in pairs(t2) do local v1 = t1[k2] if v1 == nil or not deep_compare(v1, v2) then return false end end return true end local function val_to_str(obj) local function table_key_to_str(k) if type(k) == 'string' and mw.ustring.match(k, '^[_%a][_%a%d]*$') then return k else return '[' .. val_to_str(k) .. ']' end end if type(obj) == "string" then obj = mw.ustring.gsub(obj, "\n", "\\n") if mw.ustring.match(mw.ustring.gsub(obj, '[^\'"]', ''), '^"+$') then return "'" .. obj .. "'" end return '"' .. mw.ustring.gsub(obj, '"', '\\"' ) .. '"' elseif type(obj) == "table" then local result, checked = {}, {} for k, v in ipairs(obj) do table.insert(result, val_to_str(v)) checked[k] = true end for k, v in pairs(obj) do if not checked[k] then table.insert(result, table_key_to_str(k) .. '=' .. val_to_str(v)) end end return '{' .. table.concat(result, ',') .. '}' else return tostring(obj) end end function UnitTester:equals_deep(name, actual, expected, options) num_runs = num_runs + 1 if deep_compare(actual, expected) then result_table:insert('| ', tick) else result_table:insert('| ', cross) num_failures = num_failures + 1 end local formatting = (options and options.nowiki and mw.text.nowiki) or return_varargs local actual_str = val_to_str(actual) local expected_str = val_to_str(expected) local differs_at = self.differs_at and (' \n| ' .. first_difference(expected_str, actual_str)) or '' result_table:insert(' \n| ', name, ' \n| ', formatting(expected_str), ' \n| ', formatting(actual_str), differs_at, "\n|-\n") end function UnitTester:iterate(examples, func) require 'libraryUtil'.checkType('iterate', 1, examples, 'table') if type(func) == 'string' then func = self[func] elseif type(func) ~= 'function' then error(("bad argument #2 to 'iterate' (expected function or string, got %s)") :format(type(func)), 2) end for i, example in ipairs(examples) do if type(example) == 'table' then func(self, unpack(example)) elseif type(example) == 'string' then self:heading(example) else error(('bad example #%d (expected table, got %s)') :format(i, type(example)), 2) end end end function UnitTester:heading(text) result_table:insert_format(' ! colspan="%u" style="text-align: left" | %s \n |- \n ', self.columns, text) end function UnitTester:run(frame_arg) frame = frame_arg self.frame = frame self.differs_at = frame.args['differs_at'] tick = frame:preprocess('{{Tick}}') cross = frame:preprocess('{{Cross}}') local table_header = result_table_header if frame.args['live_sandbox'] then table_header = result_table_live_sandbox_header end if frame.args.highlight then should_highlight = true end self.columns = 4 if self.differs_at then table_header = table_header .. '\n! scope="col" title="Различается на символе" | Разл. на' self.columns = self.columns + 1 end -- Sort results into alphabetical order. local self_sorted = {} for key, _ in pairs(self) do if key:find('^test') then table.insert(self_sorted, key) end end table.sort(self_sorted) -- Add results to the results table. for _, value in ipairs(self_sorted) do result_table:insert_format(table_header .. "\n|-\n", value) self[value](self) result_table:insert("|}\n") end local cat_failures = '[[Категория:Модули:Страницы с проваленными юнит-тестами]]' return (num_runs == 0 and "<b>Нет тестов для запуска.</b>" or num_failures == 0 and "<b style=\"color:#008000\">Все тесты успешно пройдены: " .. num_runs .. "</b>" or "<b style=\"color:#800000\">" .. num_failures .. " тестов из " .. num_runs .. " провалено.</b>" .. cat_failures ) .. "\n\n" .. frame:preprocess(result_table:concat()) end function UnitTester:new() local o = {} setmetatable(o, self) self.__index = self return o end local p = UnitTester:new() function p.run_tests(frame) return p:run(frame) end return p f88824c8866c120062332f00624435f8323f488b Шаблон:СИШ 10 207 463 462 2024-08-10T17:15:17Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <noinclude>{{к объединению|2020-11-10|Шаблон:High-use}} </noinclude>{{ombox |type = notice |image = [[Файл:Stalewarning.svg|40px|alt=Время]] |text = '''Внимание! Это один из [[Special:MostLinkedTemplates|самых используемых {{#ifeq: {{NAMESPACENUMBER}} | 828 | модулей | шаблонов }}]].''' |text-small = Каждое его изменение создаёт [[mw:Manual:Job queue/ru|дополнительную нагрузку]] на сервера проекта. Пожалуйста, убедитесь в адекватности и правильности ваших изменений, проверьте их на тестовых страницах.<br>[https://templatecount.toolforge.org/index.php?lang=ru&name={{PAGENAMEE}}&namespace={{NAMESPACENUMBER}} Узнать число включений]. }}<includeonly>{{no-doc|nocat={{{nocat|}}}|[[Категория:Шаблоны:С более чем 100 тысячами использований]]}}</includeonly><noinclude> {{doc}} </noinclude> 013201ef8d4ba8e3d1eb0dbba9c331a3d4ae519b Модуль:Wikidata/doc 828 208 465 464 2024-08-10T17:15:18Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{СИШ}} {{module rating|p}} {{TOC right}} Используется в {{tl|Wikidata}} (см. описания параметров там же). Настраивается при помощи [[Модуль:Wikidata/config]]. Прежде чем вносить какие-либо изменения в данный модуль, просьба оттестировать их в [[Модуль:Wikidata/песочница|/песочнице]]. Обратите внимание, что не всё корректно работает в песочнице. == Общие сведения == Функции данного модуля не предназначены для прямого вызова из шаблонов карточек или других модулей, не являющихся функциями расширения данного. Для вызова из шаблонов карточек используйте шаблон {{tl|wikidata}} или один из специализированных шаблонов для свойств. Для вызова функций Викиданных предназначенных для отображения чаще всего достаточно вызова <code>frame:expandTemplate{}</code> с вызовом шаблона, ответственного за отрисовку свойства. С другой стороны, вызов определённых функций модуля (в основном это касается <code>getEntity()</code>) может в будущем стать предпочтительным. Данный Lua-функционал в любом случае стоит рассматривать как unstable с точки зрения сохранения совместимости на уровне кода (вместе с соответствующими функциями API для Wikibase Client). Далее описывается внутренняя документация. Названия функций и параметров могут изменяться. При их изменении автор изменений обязан обновить шаблон {{tl|wikidata}} и специализированные шаблоны свойств. Изменения в других местах, если кто-то всё-таки вызывает функции модуля напрямую, остаются на совести автора «костыля». Итак, при вызове шаблона {{tl|wikidata}} или специализированного шаблона свойства управление отдаётся на функцию formatStatements, которая принимает frame. Из frame достаются следующие опции, которые так или иначе передаются в остальные функции: * <code>plain</code> — булевый переключатель (по умолчанию false). Если true, результат совпадает с обычным вызовом <code><nowiki>{{#property:pNNN}}</nowiki></code> (по факту им и будет являться) * <code>references</code> — булевый переключатель (по умолчанию true). Если true, после вывода значения параметра дополнительно выводит ссылки на источники, указанные в Викиданных. Для вывода используется [[Модуль:Sources]]. Обычно отключается для тех свойств, которые являются «самоописываемыми», например, внешними идентификаторами или ссылками (когда такая ссылка является доказательством своей актуальности), например, идентификаторы IMDb. * <code>value</code> — значение, которое надо выводить ''вместо'' значений из Викиданных (используется, если что-то задано уже в карточке в виде т. н. локального свойства) По умолчанию модуль поддерживает вывод следующих значений без дополнительных настроек: * географические координаты (coordinates) * количественные значения (quantity) * моноязычный текст (monolingualtext) * строки (string) * даты (time) Остальные типы данных требуют указания функции форматирования значения. == Кастомизация == Поддерживаются три типа параметров-функций, которые дополнительно указывают, как надо форматировать значения: * <code>property-module</code>, <code>property-function</code> — название модуля и функции модуля, которые отвечают за форматирование вывода массива значений ''свойства'' (property) с учётом квалификаторов, ссылок и прочего. Например, оформляет множество выводов в таблицу или график. Характерные примеры: ** вывод таблицы и графика населения в {{tl|wikidata/Population}} и [[Модуль:Wikidata/Population]]. *: Спецификация функции: <code>function p.…( context, options )</code>, поведение по умолчанию: [[Модуль:Wikidata#formatPropertyDefault]]. * <code>claim-module</code>, <code>claim-function</code> — название модуля и функции модуля, которые отвечают за форматирование вывода значения ''свойства'' (statement, claim) с учётом квалификаторов, ссылок и прочего. Может, например, дополнительно к основному значению (main snak) вывести значения квалификаторов. Характерные примеры: ** вывод вышестоящих административных единиц и страны в [[Модуль:Wikidata/Places]]; ** вывод авторов латинского названия и даты публикации в [[Модуль:Wikidata/Biology]]; ** вывод операционной системы и даты релиза в [[Модуль:Wikidata/Software]]; ** вывод количества и даты, на которую оно верно, в [[Модуль:Wikidata/number]]; *: Спецификация функции: <code>function p.…( context, options, statement )</code> * <code>value-module</code>, <code>value-function</code> — название модуля и функции модуля, которые отвечают за форматирование ''значения'' (snak, snak data value), в зависимости от контекста, как значений свойства, так и значений квалификатора (если вызывается из <code>claim-module/claim-function</code>). Необходимо для изменения отображения свойства, например, генерации викиссылки вместо простой строки или даже вставки изображения вместо отображения имени файла изображения (так как ссылки на изображения хранятся как строки). Характерные примеры: ** вывод ссылки на [[Викисклад]] в [[Модуль:Wikidata/media]] ** вывод ссылок на внешние сайты в [[Модуль:Wikidata/link]] *: Спецификация функции: <code>function p.…( value, options )</code> === Заготовки функций === {{Скрытый | Заголовок = property-function | Содержание = <syntaxhighlight lang="lua"> function p.formatSomeProperty( context, options ) local claims = context.selectClaims( options, options.property ); if claims == nil then return '' end local formattedStatements = {} for _, claim in ipairs( claims ) do local formattedStatement = context.formatStatement( options, claim ) -- local formattedStatement = p.formatSomeStatement( context, options, claim ) if ( formattedStatement and formattedStatement ~= '' ) then formattedStatement = context.wrapStatement( formattedStatement, options.property, claim.id ) table.insert( formattedStatements, formattedStatement ) end end return mw.text.listToText( formattedStatements, options.separator, options.conjunction ) end </syntaxhighlight> Также см. код метода <code>formatPropertyDefault</code> ниже, в нём присутствует больше проверок и работа параметрами вызова. }} {{Скрытый | Заголовок = claim-function | Содержание = <syntaxhighlight lang="lua"> function formatSomeClaim( context, options, statement ) local circumstances = context.getSourcingCircumstances( statement ); options.qualifiers = statement.qualifiers; local result = context.formatSnak( options, statement.mainsnak, circumstances ); if ( result and result ~= '' and options.references ) then result = result .. context.formatRefs( options, statement ); end return result; end </syntaxhighlight> Также см. код метода <code>formatStatementDefault</code> ниже, в нём есть пример работы с квалификаторами. }} {{Скрытый | Заголовок = value-function | Содержание = <syntaxhighlight lang="lua"> function formatSomeValue( context, options, value ) return value; end </syntaxhighlight> Также см. код метода <code>formatUrlSingle</code> в модуле [[Модуль:URL]]. }} === Context API === {{Заготовка раздела|описать публичные методы, доступные через <code>context</code>.}} ==== Переменные ==== * <code>entity</code> * <code>frame</code> ==== Методы ==== * <code>cloneOptions( options )</code> * <code>getSourcingCircumstances( statement )</code> * <code>formatProperty( options )</code> * <code>formatPropertyDefault( context, options )</code> * <code>formatSnak( options, snak, circumstances )</code> * <code>formatStatement( options, statement )</code> * <code>formatStatementDefault( context, options, statement )</code> * <code>formatRefs( options, statement )</code> * <code>formatValueDefault( context, options, value )</code> * <code>parseTimeBoundariesFromSnak( snak )</code> * <code>parseTimeFromSnak( snak )</code> * <code>selectClaims( options, propertyId )</code> * <code>wrapSnak( value, hash, attributes )</code> * <code>wrapStatement( value, propertyId, claimId, attributes )</code> * <code>wrapQualifier( value, qualifierId, attributes )</code> === Функции для форматирования === ==== property-function ==== * [[Модуль:Wikidata/date|Wikidata/date]]::formatDateIntervalProperty * [[Модуль:Wikidata/Medals|Wikidata/Medals]]::formatProperty * [[Модуль:Wikidata/Software|Wikidata/Software]]::formatVersionProperty * [[Модуль:Wikidata/P512|Wikidata/P512]]::formatAcademicDegree * [[Модуль:Wikidata/number|Wikidata/number]]::formatPropertyWithMostRecentClaimAndIndicator * [[Модуль:Wikidata/number|Wikidata/number]]::formatColorIndex ==== claim-function ==== * [[Модуль:Wikidata/Places|Wikidata/Places]]::formatCountryClaimWithFlag * [[Модуль:Wikidata/Places|Wikidata/Places]]::formatPlaceWithQualifiers * [[Модуль:Wikidata/item|Wikidata/item]]::formatEntityWithGenderClaim * [[Модуль:Wikidata/Biology|Wikidata/Biology]]::formatTaxonNameClaim * [[Модуль:Wikidata/item|Wikidata/item]]::applyDefaultTemplate * [[Модуль:Wikidata/date|Wikidata/date]]::formatDateOfBirthClaim * [[Модуль:Wikidata/date|Wikidata/date]]::formatDateOfDeathClaim ==== value-function ==== * [[Модуль:Wikidata|Wikidata]]::extractCategory * [[Модуль:Wikidata/link|Wikidata/link]]::fromModule * [[Модуль:Wikidata/Medals|Wikidata/Medals]]::formatValue * [[Модуль:Wikidata/media|Wikidata/media]]::formatCommonsCategory * [[Модуль:Wikidata/Software|Wikidata/Software]]::formatExtension * [[Модуль:Wikidata/number|Wikidata/number]]::formatRA * [[Модуль:Wikidata/number|Wikidata/number]]::formatDMS * [[Модуль:Wikidata/url|Wikidata/url]]::formatUrlValue * [[Модуль:Wikidata/url|Wikidata/url]]::formatLangRefs == Тесты == {{Скрытый | Заголовок = [[Модуль:Wikidata/tests]] | Содержание = {{#invoke:Wikidata/tests|run_tests}} }} == См. также == * [[Модуль:Wikibase]] * Независимые иноязычные аналоги: ** [[:fr:Module:Wikidata]] ** [[:ca:Mòdul:Wikidades]] ** [[:it:Modulo:Wikidata]] ** [[:de:Modul:Wikidata]] ** [[:en:Module:WikidataIB]] ** [[:en:Module:Wd]] <noinclude> [[Категория:Модули:Документация]] </noinclude> <includeonly> [[Категория:Модули:Викиданные]] </includeonly> 1e00ff235ce39f7fd8e5927f57fda177a193a7a6 Модуль:Message box/ambox.css 828 209 467 466 2024-08-10T17:15:19Z DuOfOrl 5 1 версия импортирована sanitized-css text/css /* Скопировано из [[:en:Module:Message box/ambox.css]] с изменениями */ .ambox { border: 1px solid var(--border-color-base, #a2a9b1); /* @noflip */ border-left: 10px solid #36c; /* Default "notice" blue */ background: var(--background-color-neutral-subtle, #f8f9fa); box-sizing: border-box; margin: 0 10%; } /* Не ухудшаем стили для Минервы */ html body.mediawiki.skin-minerva .ambox { border-width: 0 0 0 4px; } /* Single border between stacked boxes. Take into account base templatestyles, * user styles, and Template:Dated maintenance category. * remove link selector when T200206 is fixed */ .ambox + link + .ambox, .ambox + link + style + .ambox, .ambox + link + link + .ambox, /* TODO: raise these as "is this really that necessary???". the change was Dec 2021 */ .ambox + .mw-empty-elt + link + .ambox, .ambox + .mw-empty-elt + link + style + .ambox, .ambox + .mw-empty-elt + link + link + .ambox { margin-top: -1px; } /* For the "small=left" option. */ /* must override .ambox + .ambox styles above */ html body.mediawiki .ambox.mbox-small-left { /* @noflip */ margin: 4px 1em 4px 0; overflow: hidden; width: 238px; border-collapse: collapse; font-size: 88%; line-height: 1.25em; } .ambox-speedy { /* @noflip */ border-left: 10px solid var(--border-color-error, #b32424); /* Red */ background-color: var(--background-color-error-subtle, #fee7e6); /* Pink */ } .ambox-delete { /* @noflip */ border-left: 10px solid var(--border-color-error, #b32424); /* Red */ } .ambox-content { /* @noflip */ border-left: 10px solid #f28500; /* Orange */ } .ambox-style { /* @noflip */ border-left: 10px solid var(--color-warning, #edab00); /* Yellow */ } .ambox-good { /* @noflip */ border-left: 10px solid #66cc44; } .ambox-discussion { /* @noflip */ border-left: 10px solid #339966; } .ambox-merge { /* @noflip */ border-left: 10px solid #9932cc; } .ambox-move { /* @noflip */ border-left: 10px solid #9932cc; /* Purple */ } .ambox-protection { /* @noflip */ border-left: 10px solid #a2a9b1; /* Gray-gold */ } .ambox .mbox-text { border: none; /* @noflip */ padding: 0.25em 0.5em; width: 100%; } .ambox .mbox-image { border: none; /* @noflip */ padding: 2px 0 2px 0.5em; text-align: center; } .ambox .mbox-imageright { border: none; /* @noflip */ padding: 2px 0.5em 2px 0; text-align: center; } /* An empty narrow cell */ .ambox .mbox-empty-cell { border: none; padding: 0; width: 1px; } .ambox .mbox-image-div { width: 52px; } /* Хак, TODO: посмотреть, как оно на самом деле работает */ .ambox .mbox-textsmall-div { font-size: 90%; } /* Hack around MobileFrontend being opinionated */ html.client-js body.skin-minerva .mbox-text-span { margin-left: 23px !important; } /* Стили нотификаций для ноутбуков */ @media (max-width: 1366px) { .ambox { margin-left: 6%; margin-right: 6%; } } /* Стили нотификаций для мобильного устройсва */ @media (max-width: 719px) { .ambox { margin-left: 0; margin-right: 0; } } /* [[Категория:Модули:Подстраницы CSS]] */ 1d03f5efb7ec589bb5edde009c3ae9ef13460e7e Модуль:Wikidata/tests 828 210 469 468 2024-08-10T17:15:19Z DuOfOrl 5 1 версия импортирована Scribunto text/plain -- Unit tests for [[Module:URL]]. Click talk page to run tests. local p = require( 'Module:UnitTests' ) local wd = require( 'Module:Wikidata' ) local getSnak = function( timeString ) return { datatype = "time", datavalue = { type = "time", value = { after = 0, before = 0, calendarmodel = "http://www.wikidata.org/entity/Q1985727", precision = 11, time = timeString, timezone = 0, }, }, hash = "33bd9a339157ce7b3d74cb10d73bc23529c9a7f3", property = "P585", snaktype = "value", } end function p:test_parseTimeBoundaries() self:equals_deep( '2000-12-31', wd._parseTimeBoundaries( '+2000-12-31T00:00:00Z', 11 ), { 978220800000, 978307199999 } ) self:equals_deep( '2001-01-01', wd._parseTimeBoundaries( '+2001-01-01T00:00:00Z', 11 ), { 978307200000, 978393599999 } ) self:equals_deep( '2001', wd._parseTimeBoundaries( '+2001-00-00T00:00:00Z', 9 ), { 978307200000, 1009843199999 } ) end function p:test_parseTimeFromSnak() self:equals_deep( '2000-12-31', wd._parseTimeFromSnak( getSnak( '+2000-12-31T00:00:00Z' ) ), 978220800000 ) self:equals_deep( '2001-01-01', wd._parseTimeFromSnak( getSnak( '+2001-01-01T00:00:00Z' ) ), 978307200000 ) self:equals_deep( '2001', wd._parseTimeFromSnak( getSnak( '+2001-00-00T00:00:00Z' ) ), 978307200000 ) end return p a49c6e32801a352e27ec0dee7b1af3c93a0f5c10 Модуль:Infobox 828 211 471 470 2024-08-10T17:21:56Z DuOfOrl 5 1 версия импортирована Scribunto text/plain local p = {}; local yesno = require('Module:Yesno') local function _renderLine( frame, args, i ) if args[ 'заголовок' .. i ] and args[ 'заголовок' .. i ] == '-' then return '' elseif args[ 'заголовок' .. i ] and args[ 'заголовок' .. i ] ~= '' then local style = ( args[ 'стиль_заголовков' ] or '' ) .. ( args[ 'стиль_заголовка' .. i ] or '' ); local class = ( args[ 'класс' .. i ] or '' ); return '\n<tr>\n<th colspan="2" scope="colgroup" class="infobox-header ' .. class .. '" style="' .. style .. '">' .. args[ 'заголовок' .. i ] .. '</th>\n</tr>'; end if args[ 'блок' .. i ] and args[ 'блок' .. i ] ~= '' then return args[ 'блок' .. i ]; end local text = args[ 'текст' .. i ] or ''; if args[ 'викиданные' .. i ] and args[ 'викиданные' .. i ] ~= '' then text = frame:expandTemplate{ title = 'Wikidata', args = { args[ 'викиданные' .. i ], text, from = args[ 'from' ] or '' } }; end if text ~= '' then local label = args[ 'метка' .. i ] or ''; local class = args[ 'класс' .. i ] or ''; if string.find(class, 'noplainlist') == nil and string.find(class, 'nofirstlevel') == nil then class = class .. ' plainlist'; end if class ~= '' then class = ' class="' .. class .. '"'; end local style = ( args[ 'стиль_текстов' ] or '' ) .. ( args[ 'стиль_текста' ] or '' ) .. ( args[ 'стиль_текста' .. i ] or '' ); if label == '' then style = 'text-align:center;' .. style; end if style ~= '' then style = ' style="' .. style .. '"'; end if label ~= '' then local labelClass = args[ 'класс_меток' ] or ''; if string.find(labelClass, 'noplainlist') == nil and string.find(labelClass, 'nofirstlevel') == nil then labelClass = labelClass .. ' plainlist'; end if labelClass ~= '' then labelClass = ' class="' .. labelClass .. '"'; end local labelStyle = ( args[ 'стиль_меток' ] or '' ) .. ( args[ 'стиль_метки' .. i ] or '' ); if labelStyle ~= '' then labelStyle = ' style="' .. labelStyle .. '"'; end return '\n<tr>\n<th scope="row"' .. labelClass .. labelStyle .. '>' .. label .. '</th>' .. '\n<td' .. class .. style .. '>\n' .. text .. '</td>\n</tr>'; end return '\n<tr>\n<td colspan="2"' .. class .. style .. '>\n' .. text .. '</td>\n</tr>'; end return ''; end local function maxNumber ( args ) local maxNumber = 0 for argName, _ in pairs(args) do local argNumber = mw.ustring.match(argName, '^[^0-9]+([0-9]+)$') if argNumber and tonumber(argNumber) > maxNumber then maxNumber = tonumber(argNumber) end end return maxNumber end function p.renderLine( frame ) local args = frame:getParent().args; return _renderLine(frame, args, '') end function p.renderLines( frame ) local args = frame:getParent().args; local res = '' local header, text = '', '' local autoHeaders = yesno(args [ 'автозаголовки' ] or 'false', false) for i = 1, maxNumber(args) do if args[ 'заголовок' .. i ] and args[ 'заголовок' .. i ] ~= '' then if text ~= '' or not autoHeaders then res = res .. header .. text end header, text = _renderLine(frame, args, i), '' else text = text .. _renderLine(frame, args, i) end end if text ~= '' or not autoHeaders then res = res .. header .. text end return res end return p; c830c997bd3d15923f347277e3b0ae71b7ba917e Шаблон:Политик/doc 10 304 769 2024-08-15T11:45:35Z ruwiki>A particle for world to form 0 ? wikitext text/x-wiki {{docpage}} {{OnLua|CategoryForProfession}} {{Установлена проверка на неизвестные параметры}} {{Uses Wikidata|p18|p19|p20|p22|p25|p27|p40|p102|p106|p109|p140|p166|p512|p569|p570|p856|p1142|p1559}} Этот [[Википедия:Шаблоны-карточки|шаблон-карточка]] предназначен для статей о политиках. Для государственных деятелей существует шаблон {{t|Государственный деятель}}. Внимание, шаблон поддерживает загрузку дат смерти и рождения через [[ВП:Викиданные|Викиданные]]. Не заполняйте в шаблоне эти поля, если есть возможность использовать wikidata. ''Отметим, что большинство полей автоматически загружают информации из [[ВП:Викиданные|Викиданных]].'' Категории профессий по алфавиту и по странам добавляются автоматически на основе информации из викиданных. В случае если персоналию не следует добавлять в категорию, то существует параметр <code>без категорий=</code> в которым следует перечислить названия исключаемых категорий через точку с запятой. Пример использования — [[Special:Diff/70059213/70085957]]. Если есть только год рождения/смерти, так и пишите только цифры года. {{Старый-новый стиль,примечание}} == Заготовка для копирования == {{Заготовка шаблона}} == Пример использования == {{Пример шаблона}} == Отслеживающие категории == В служебных целях используется ряд скрытых отслеживающих категорий: {{categorytree|Отслеживающие категории:Шаблон:Политик|категории|0|title=}} == TemplateData == <templatedata> { "params": { "nocat": { "type": "boolean" }, "from": { "type": "line" }, "имя": { "aliases": [ "Имя" ], "label": "имя", "description": "имя персоны", "type": "line", "example": "Джон Доу" }, "оригинал имени": { "aliases": [ "Оригинал имени" ], "label": "оригинал имени", "description": "имя персоны на языке оригинала, обёрнутое в шаблон серии {{t|lang-en}}", "example": "{{lang-en|John Doe}}", "type": "string" }, "изображение": { "aliases": [ "Изображение" ], "label": "изображение", "description": "изображение персоны (P18)", "example": "example.jpg", "type": "wiki-file-name" }, "ширина": { "aliases": [ "Ширина" ], "label": "ширина", "type": "number", "description": "размер изображения" }, "описание изображения": { "aliases": [ "Описание изображения" ], "label": "описание изображения", "description": "должно характеризовать портрет", "type": "string" }, "имя при рождении": { "aliases": [ "Имя при рождении" ], "label": "имя при рождении", "description": "имя при рождении, если было изменено", "type": "string" }, "псевдонимы": { "aliases": [ "Псевдонимы" ], "label": "псевдонимы", "type": "string" }, "дата рождения": { "aliases": [ "Дата рождения" ], "label": "дата рождения", "type": "date", "description": "дд.мм.гггг (P569)", "example": "02.01.1960" }, "дата смерти": { "aliases": [ "Дата смерти" ], "label": "дата смерти", "type": "date", "description": "дд.мм.гггг (P570)", "example": "02.01.2000" }, "место рождения": { "aliases": [ "Место рождения" ], "label": "место рождения", "description": "место рождения (P19)", "type": "string", "example": "{{МестоРождения|Лондон}}", "autovalue": "{{МестоРождения|}}" }, "место смерти": { "aliases": [ "Место смерти" ], "label": "место смерти", "description": "место смерти (P20)", "type": "string", "example": "{{МестоСмерти|Москва}}", "autovalue": "{{МестоСмерти|}}" }, "гражданство": { "aliases": [ "Гражданство", "страна", "подданство" ], "label": "гражданство", "description": "гражданство (P27)", "type": "string", "example": "[[Великобритания]], [[Россия]]" }, "род деятельности": { "aliases": [ "Род деятельности" ], "label": "род деятельности", "description": "род деятельности (P106)", "type": "string", "example": "[[политик]], [[журналист]], [[издатель]]" }, "образование": { "aliases": [ "Образование", "альма-матер" ], "label": "образование", "description": "оконченное высшее учебное заведение (P69)", "type": "string", "example": "[[Московский государственный университет]]" }, "учёная степень": { "aliases": [ "Учёная степень" ], "label": "учёная степень", "type": "string", "description": "учёная степень (P512)", "example": "{{Учёная степень|доктор|экономических наук}}", "autovalue": "{{Учёная степень||}}" }, "вероисповедание": { "aliases": [ "Вероисповедание" ], "label": "вероисповедание", "type": "string", "description": "вероисповедание персоны", "example": "[[католицизм]]" }, "партия": { "aliases": [ "Партия" ], "label": "партия", "type": "string", "description": "партии и организации", "example": "[[КПСС]], [[Партия любителей пива]]" }, "основные идеи": { "aliases": [ "Основные идеи" ], "label": "основные идеи", "type": "string", "description": "политические взгляды и основные идеи (P1142)", "example": "[[коммунизм]], [[национализм]]" }, "отец": { "aliases": [ "Отец" ], "label": "отец", "description": "отец (P22)", "type": "string" }, "мать": { "aliases": [ "Мать" ], "label": "мать", "description": "мать (P25)", "type": "string" }, "супруг": { "aliases": [ "Супруг" ], "label": "супруг", "description": "супруг (P26)", "type": "string" }, "супруга": { "aliases": [ "Супруга" ], "label": "супруга", "description": "супруга (P26)", "type": "string" }, "дети": { "aliases": [ "Дети" ], "label": "дети", "description": "дети (P40)", "type": "string" }, "награды": { "aliases": [ "Награды", "награды и премии" ], "label": "награды", "description": "ордена, медали и тому подобное; для них есть специальные шаблоны (P166)", "type": "string", "example": "{{ряд | {{Орден Ленина}} | {{Орден Октябрьской Революции}} | {{Орден Красного Знамени}} }}" }, "автограф": { "aliases": [ "Автограф" ], "label": "автограф", "type": "wiki-file-name", "description": "отсканированная подпись персоны (P109)" }, "ширина автографа": { "aliases": [ "Ширина автографа" ], "label": "ширина автографа", "type": "number" }, "сайт": { "aliases": [ "Сайт" ], "label": "сайт", "type": "url", "description": "официальный сайт (P856)", "example": "example.com" }, "викисклад": { "aliases": [ "Викисклад" ], "label": "викисклад", "description": "название категории на Викискладе (P373)", "deprecated": true, "type": "line" }, "учёное звание": { "aliases": [ "Учёное звание" ], "label": "учёное звание", "type": "string", "description": "учёное звание", "example": "{{Учёное звание||0}}", "autovalue": "{{Учёное звание||}}" } }, "description": "Шаблон-карточка для статей о политиках.", "paramOrder": [ "имя", "оригинал имени", "изображение", "ширина", "описание изображения", "имя при рождении", "псевдонимы", "дата рождения", "место рождения", "дата смерти", "место смерти", "гражданство", "род деятельности", "образование", "учёная степень", "учёное звание", "вероисповедание", "партия", "основные идеи", "отец", "мать", "супруг", "супруга", "дети", "награды", "автограф", "ширина автографа", "сайт", "викисклад", "nocat", "from" ], "format": "block" } </templatedata> <includeonly> [[Категория:Шаблоны-карточки:Личности]] [[Категория:Шаблоны-карточки:Политика]] </includeonly> 20627691b0800f1de81471e82cb15ed1027bfbd3 Шаблон:Карточка/изображение 10 213 475 474 2024-08-16T05:22:07Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <includeonly>{{#if:{{{1|}}}| {{#switch:{{{1|}}} |-=- |none= |нет= |{{#switch:{{str left|{{{1|}}}|1}} |[|<|{|={{{1|}}} |[[Файл:{{{1|}}}|{{#if:{{{size|{{{2|}}}}}}|{{#ifeq:{{str rightc|{{{size|{{{2|}}}}}}|2}}|px|{{{size|{{{2|}}}}}}|{{#ifeq:{{str rightc|{{{size|{{{2|}}}}}}|3}}|пкс|{{{size|{{{2|}}}}}}|{{{size|{{{2|}}}}}}px}}}}|274x400px}}{{#if:{{{caption|}}}|{{!}}{{{caption|}}}}}|frameless{{#if:{{{border|}}}|{{!}}border}}{{#if:{{{alt|}}}|{{!}}alt={{{alt|}}}}}]] }}{{#if:{{{caption|}}} |<span class="media-caption" style="display:block;">{{{caption|}}}</span> }} }} }}</includeonly><!-- -->{{#if: {{{2|}}} | [[Категория:Википедия:Страницы с использованием устаревшего формата параметра Карточка/изображение]] }}<!-- -->{{#ifeq: {{str find|{{{size|{{{2|}}}}}}|pxpx}} | -1 || [[Категория:Википедия:Изображение с pxpx в размере]] }}<noinclude>{{doc}}</noinclude> c54dd8fbf131f3bc584add9cd834eea7b4f45e43 Шаблон:Str find 10 214 477 476 2024-08-16T05:22:14Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{ {{{|safesubst:}}}#invoke:String|str_find|source={{{1|}}}|{{{2|}}}}}<noinclude> {{doc}} <!-- Add categories and interwikis to the /doc subpage, not here! --> </noinclude> 18d1469d30d27a82ee15fd2fb1ca12a34b5f5e87 Шаблон:Навигационная таблица 10 215 479 478 2024-08-16T05:22:16Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <includeonly>{{#invoke:Navbox|navbox}}</includeonly>{{#ifeq: {{NAMESPACE}} | Шаблон | {{#switch: {{{1|{{{border|}}}}}} | child | subgroup | none = | {{#ifeq: {{{имя|{{{name|}}}}}} | {{PAGENAME}} | | {{#if:{{yesno|{{{tracking|}}}|no=1|yes=|blank=}} | | {{#if: {{{имя|{{{name|}}}}}} | {{#ifeq:{{ROOTPAGENAME}}|Работа недели||{{no-doc|[[Категория:Навигационные шаблоны, у которых нужно проверить параметр Имя]]}}}} | [[Категория:Навигационные шаблоны, у которых предположительно недостаёт параметра Имя]] }} }} }} }} }}<noinclude> {{doc}} </noinclude> b1c7f6e61d3b9cdd1daaf4d95e30e299a1d9eb5c Шаблон:Tp 10 216 481 480 2024-08-16T05:22:19Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki #перенаправление [[Шаблон:Tlp]] d882ad71d959bf88034ac86b892a2686c44e6a87 Шаблон:Tlp 10 217 483 482 2024-08-16T05:22:20Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{{{{|safesubst:}}}#invoke: Template call code | withParams | _link = 1 }}<noinclude>{{doc}}</noinclude> 36c309cb28ccf0901f4fff46cbd35cdabcf00661 Шаблон:Para 10 218 485 484 2024-08-16T05:22:22Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <code style="white-space:nowrap;">&#124;{{#if:{{{1|}}}|<span style="color:#767600;">{{{1}}}</span> &#61; {{{2|}}}|<span style="color:#767600;">{{{2|}}}</span>}}</code><noinclude> {{doc}} </noinclude> 2fd0e9f403fb5a42e97b773185e89bc43323bb37 Шаблон:Tnav 10 219 487 486 2024-08-16T05:22:24Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{t|{{{1|}}}|nav|comment={{{comment|}}}}}<noinclude> {{doc-inline}} Это — обёртка для шаблона {{t|tl}}, предназначенная для использования в блоках навигации. Она передаёт в него флаг <code>nav</code> и комментарий в параметре {{para|comment}}. {{шаблоны для документирования}} {{doc-end}} [[Категория:Шаблоны:Ссылки на шаблоны]] [[Категория:Шаблоны:Для навигационных шаблонов]] </noinclude> 583d607aa213790ae32dda4018a413255493e42b Шаблон:High-use 10 220 489 488 2024-08-16T05:22:25Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <noinclude>{{к удалению|2024-04-08}} </noinclude><noinclude>{{к объединению|2020-11-10|Шаблон:СИШ}}</noinclude>{{ombox | type = style | image = [[File:OOjs UI icon alert-yellow.svg|40px|alt=|link=]] | text = Этот {{#switch: {{NAMESPACE}} | Модуль = модуль | #default = шаблон }} используется на многих страницах, поэтому изменения в нём будут заметны многим. Пожалуйста, протестируйте любые изменения в песочнице или на вашей личной подстранице. Рассмотрите возможность обсуждения изменений на [[{{#switch: {{SUBPAGENAME}} | doc | sandbox = {{TALKSPACE}}:{{BASEPAGENAME}} | #default = {{TALKPAGENAME}} }}|странице обсуждения]] или [[ВП:Форум|форуме]] перед их внесением.<br>[https://templatecount.toolforge.org/index.php?lang=ru&name={{PAGENAMEE}}&namespace={{NAMESPACENUMBER}} Узнать число включений]. }}<includeonly>{{no-doc|nocat={{{nocat|}}}| [[Категория:Шаблоны:Критические]] }}</includeonly><noinclude>{{doc}}</noinclude> ded73fd2acfa6bc0f9f309d7d66181c33a520198 Шаблон:Подстраницы шаблона Карточка 10 221 491 490 2024-08-16T05:22:26Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{Навигационная таблица |имя = Подстраницы шаблона Карточка |state = {{{state|}}} |класс_списков = hlist hlist-items-nowrap |заголовок = Подстраницы шаблона {{tnav|Карточка}} |tracking = <includeonly>no</includeonly> |группа1 = {{!}}вверху= |список1 = * {{tnav|карточка/название}} (заголовок без уточнения) * {{tnav|карточка/имя}} (заголовок в обратном порядке и без уточнения) |группа2 = {{!}}вверху2= |список2 = * {{tnav|карточка/оригинал названия}} (свойство [[d:P:P1705|P1705]]) * {{tnav|карточка/оригинал названия произведения}} (свойство [[d:P:P1476|P1476]]) * {{tnav|карточка/официальное название}} (свойство [[d:P:P1448|P1448]]) * {{tnav|карточка/оригинал имени}} (свойство [[d:P:P1559|P1559]]) |группа3 = Разное |список3 = * {{tnav|карточка/изображение}} * {{tnav|карточка/Изображение рядом}} * {{tnav|карточка/флаг и герб}} (свойства [[d:p:P41|P41]] и [[d:p:P94|P94]]) * {{tnav|карточка/медали}} (свойство [[d:p:P166|P166]]) * {{tnav|карточка/хронология}} (свойства [[d:p:P155|P155]] и [[d:p:P156|P156]]) * {{tnav|карточка/период}} (свойства [[d:p:P580|P580]] и [[d:p:P582|P582]]) * {{tnav|карточка/коды в каталогах}} (свойство [[d:p:P528|P528]]) * {{tnav|карточка/блок}} * {{tnav|карточка/блок с маркерами}} |группа4 = {{!}}внизу= |список4 = * {{tnav|карточка/Викиданные}} * {{tnav|карточка/Викисклад}} (свойство [[d:P:P373|P373]]) * {{tnav|карточка/Викитека}} * {{tnav|карточка/Викиучебник}} * {{tnav|карточка/Викицитатник}} |класс_внизу = hlist |внизу = ; См. также : [[Википедия:Шаблоны-карточки]] : [[:Категория:Шаблоны:Для шаблонов-карточек]] }}<noinclude> [[Категория:Навигационные шаблоны:Для шаблонов]] </noinclude> f7c3cb19df3f1a23fdde48e58f259bb1f952d0ed Шаблон:Карточка/изображение/doc 10 222 493 492 2024-08-16T05:22:26Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{docpage}} {{high-use}} Используется в [[Википедия:Шаблоны-карточки|шаблонах-карточках]] для вывода полей изображений, которые не нужно привязывать к Викиданным (в противном случае используется <code>{{tp|wikidata|P18|caption=<nowiki>{{{описание изображения|}}}</nowiki>|size=<nowiki>{{{ширина|}}}</nowiki>}}</code>). == Заполнение в статьях == Для изображений в формате «'''<nowiki>[[Файл:<Имя>|…]]</nowiki>'''» (и вообще для любого параметра, начинающегося с «'''['''», «'''{'''» или «'''<'''») текст вставится без изменения: <nowiki>{{{изображение|}}}</nowiki> Если же просто указано название изображения, то оно оформится так: <nowiki>[[Файл:{{{изображение|}}}|274x400px]]</nowiki> == Использование шаблона == Вставляется в шаблон {{t|карточка}} — либо в поле {{para|изображение}}, либо в поле {{para|текстN}} (в таком случае может понадобиться сбросить паддинги: {{para|стиль_текстаN|padding:0;}}). Формат применения: <nowiki>| изображение = {{Карточка/изображение|{{{изображение|}}}|size={{{ширина|}}}|caption={{{описание изображения|}}}}}</nowiki> == TemplateData == <templatedata> { "description": "Этот шаблон используется для вставки параметра изображения.", "params": { "1": { "label": "1", "description": "Изображение в любом виде, если '''none''' или '''нет''', то игнорируется.", "type": "string", "required": false }, "caption": { "label": "caption", "description": "Подпись под изображением.", "type": "string", "required": false }, "size": { "aliases": [ "2" ], "label": "size", "description": "Его размер, можно с '''px''' или без, по-умолчанию — '''274x400px'''.", "type": "string" } }, "paramOrder": [ "1", "size", "caption" ] } </templatedata> == См. также == * [[Шаблон:Карточка/изображение/тесты]] (для проверки изменений) * {{tl|URL}} {{Подстраницы шаблона Карточка}} <includeonly> [[Категория:Шаблоны:Подстраницы шаблона Карточка|изображение]] </includeonly> 1a53aa3106ad42492ac93048c8554950e40a1bf8 Шаблон:Fmbox 10 223 495 494 2024-08-16T05:24:30Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{#invoke:Message box|fmbox}}<noinclude> {{documentation}} <!-- Add categories and interwikis to the /doc subpage, not here! --> </noinclude> dfb511d767bd2208627c0874ccf91faf6b8551cc Шаблон:Параметры шаблона 10 224 497 496 2024-08-16T05:24:33Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <span title="Смотреть с помощью инструмента Templatetiger">[//dimastbkbot.toolforge.org/template_params/?template={{urlencode:{{{1|{{PAGENAME}}}}}}}&lang=ruwiki использование шаблона]</span><!-- &nbsp;&bull; <span title="Смотреть с помощью инструмента Templatetiger">[//tools.wmflabs.org/templatetiger/template-parameter.php?template={{urlencode:{{{1|{{PAGENAME}}}}}}}&lang=ruwiki параметры]--> <small>[[Шаблон:Параметры шаблона|[?]]]</small><!--</span>--><noinclude>{{doc}}</noinclude> dcd4178efbe8f098263608dce37fd93b55b863c4 Модуль:Message box/fmbox.css 828 225 499 498 2024-08-16T05:24:34Z DuOfOrl 5 1 версия импортирована sanitized-css text/css /* Скопировано из [[:en:Module:Message box/fmbox.css]] с изменениями */ .fmbox { clear: both; margin: 0.2em 0; width: 100%; border: 1px solid var(--border-color-base, #a2a9b1); background-color: var(--background-color-neutral-subtle, #f8f9fa); /* Default "system" gray */ box-sizing: border-box; } .fmbox-warning { border: 1px solid #bb7070; /* Dark pink */ background-color: #ffdbdb; /* Pink */ } .fmbox-editnotice { background-color: transparent; } .fmbox .mbox-text { border: none; /* @noflip */ padding: 0.25em 0.9em; width: 100%; } .fmbox .mbox-image { border: none; /* @noflip */ padding: 2px 0 2px 0.9em; text-align: center; } .fmbox .mbox-imageright { border: none; /* @noflip */ padding: 2px 0.9em 2px 0; text-align: center; } .fmbox .mbox-invalid-type { text-align: center; } /* Хак, TODO: посмотреть, как оно на самом деле работает */ .fmbox .mbox-textsmall-div { font-size: 90%; } /* [[Категория:Модули:Подстраницы CSS]] */ 313e9f5515a4f12a2a44d6c8d57f74cbda4bb464 Шаблон:Государство 10 122 500 287 2024-08-16T05:28:56Z DuOfOrl 5 wikitext text/x-wiki {{Карточка |имя = Государство |автозаголовки = да |from = {{{from|}}} |вверху0 = {{#switch: {{{Статус|}}} | виртуальное = [[Виртуальное государство]] | особый = {{#if: {{{Спорный статус|}}} | {{{Особый спорный статус|}}} }} | Непризнанное | непризнанное = {{#if: {{{Спорный статус|}}} | [[Непризнанные и частично признанные государства|Непризнанное государство]] }} | Частично признанное | частично признанное = {{#if: {{{Спорный статус|}}} | [[Непризнанные и частично признанные государства|Частично признанное государство]] }} }} |вверху = {{карточка/название|{{{Русское название|}}}|from={{{from|}}}}} |вверху2 = {{{Оригинальное название|}}} |изображение = {{Карточка/флаг и герб | флаг = {{{Флаг|}}} | флаг ширина = {{{Размер флага|}}}{{{размер флага|}}} | флаг подпись = [[{{#if: {{{Ссылка на флаг|}}} | {{{Ссылка на флаг}}} | Флаг {{{Родительный падеж}}} }}|Флаг]] | герб = {{{Герб|}}} | герб ширина = {{{Размер герба|}}}{{{размер герба|}}} | герб подпись = {{#if: {{{Отображаемая подпись герба|}}} | {{{Отображаемая подпись герба}}} | {{#if: {{{Вместо герба|}}} | [[{{{Вместо герба}}} {{{Родительный падеж}}}|{{{Вместо герба}}}]] | [[Герб {{{Родительный падеж}}}|Герб]] }} }} |from={{{from|}}}}} |текст1 = {{br separated entries | {{#if: {{{Девиз|}}} | [[Девиз]]: ''«{{{Девиз}}}»'' }} | {{#if: {{{Перевод девиза|}}} | ''«{{{Перевод девиза}}}»'' }} }} |текст2 = {{#if: {{{Без гимна|}}} || {{#if: {{{Название гимна|}}} | [[Государственный гимн|Гимн]]: [[Гимн {{{Родительный падеж}}}|''«{{{Название гимна}}}»'']] | [[Гимн {{{Родительный падеж<noinclude>|</noinclude>}}}|Государственный гимн {{{Родительный падеж<noinclude>|</noinclude>}}}]] }}{{#if: {{{Аудио|}}} | {{#if: {{{Аудио|}}} | <sup>[[Файл:Loudspeaker.svg|11px|link=Файл:{{{1}}}|Информация о файле]] [[:Media:{{{Аудио|}}}|слушать]]</sup> }} }} }} |текст3 = {{#if: {{{На карте|}}} | {{Карточка/изображение|{{{На карте|}}}|size={{#if: {{{Размер карты|}}}{{{размер карты|}}} | {{{Размер карты|}}}{{{размер карты|}}} | 300x300px }}|caption={{{Подпись к карте|}}}{{{подпись к карте|}}}}}<!-- -->{{#if: {{{На карте2|}}} | <br>[[Файл:{{{На карте2}}}|{{{Размер карты2|{{{размер карты2|300x300px}}}}}}]]{{#if:{{{Подпись к карте 2|}}}{{{подпись к карте 2|}}}|<br>{{{Подпись к карте 2|{{{подпись к карте 2|}}}}}} }} }} }} |заголовок4 = {{#if: {{{sovereignty_type|}}} | {{{sovereignty_type}}} | [[История {{{Родительный падеж}}}|История]] }} |стиль_заголовка4 = padding-bottom:0; border-bottom:0; text-align:left; |блок5 = {{Карточка/блок с маркерами |метка1 = {{nobr|{{{Дата1}}}}} |текст1 = {{{Этап1|}}} |метка2 = {{nobr|{{{Дата2}}}}} |текст2 = {{{Этап2|}}} |метка3 = {{nobr|{{{Дата3}}}}} |текст3 = {{{Этап3|}}} |метка4 = {{nobr|{{{Дата4}}}}} |текст4 = {{{Этап4|}}} |метка5 = {{nobr|{{{Дата5}}}}} |текст5 = {{{Этап5|}}} |метка6 = {{nobr|{{{Дата6}}}}} |текст6 = {{{Этап6|}}} |метка7 = {{nobr|{{{Дата7}}}}} |текст7 = {{{Этап7|}}} |метка8 = {{nobr|{{{Дата8}}}}} |текст8 = {{{Этап8|}}} |метка9 = {{nobr|{{{Дата9}}}}} |текст9 = {{{Этап9|}}} |метка10 = {{nobr|{{{Дата10}}}}} |текст10 = {{{Этап10|}}} |метка11 = {{nobr|{{{Дата11}}}}} |текст11 = {{{Этап11|}}} |метка12 = {{nobr|{{{Дата12}}}}} |текст12 = {{{Этап12|}}} |from={{{from|}}}}} |заголовок6 = - |метка7 = [[Основание государства|{{#if: {{{Основана|}}} | Основана | Основано }}]] |текст7 = {{{Основана|}}}{{{Основано|}}} <!-- СПОРНЫЙ СТАТУС --> <!-- Спорный статус заполнен --> |метка8 = [[Основание государства|Дата образования]] |текст8 = {{#if: {{{Спорный статус|}}} | {{{Дата образования|}}} }} |метка9 = Провозглашение независимости |текст9 = {{#if: {{{Спорный статус|}}} | {{#if: {{{Провозглашение независимости|}}} | {{{Провозглашение независимости}}} {{#if: {{{Независимость от|}}} | (от&nbsp;{{{Независимость от}}}) }} }} }} |метка10 = [[Международно-правовое признание|Дипломатическое признание]] |текст10 = {{#if: {{{Спорный статус|}}} | {{{Дипломатическое признание|}}} }} <!-- Спорный статус не заполнен --> |метка11 = {{#if: {{{Отображаемый тип независимости|}}} | {{{Отображаемый тип независимости}}} | [[Суверенитет|{{#if: {{{Даты независимости|}}} | Даты | Дата }} независимости]] }} |текст11 = {{#if: {{{Спорный статус|}}} || {{#if: {{{Дата независимости|}}}{{{Даты независимости|}}} | {{{Дата независимости|{{{Даты независимости|}}}}}} {{#if: {{{Независимость от|}}} | (от&nbsp;{{{Независимость от}}}) }} }} }} <!-- / СПОРНЫЙ СТАТУС --> |метка12 = [[Официальный язык|{{#if: {{{Язык|}}} | Официальный язык | Официальные языки }}]] |текст12 = {{{Язык|{{{Языки|}}}}}} |метка13 = [[Столица]] |текст13 = {{{Столица|}}} |метка14 = {{#if: {{{Крупнейший город|}}} | Крупнейший город | Крупнейшие города }} |текст14 = {{{Крупнейший город|}}}{{{Крупнейшие города|}}} |метка15 = [[Форма государственного правления|Форма правления]] |текст15 = {{{Форма правления|}}} |метка16 = [[Форма государственного устройства|Государственный строй]] |текст16 = {{{Государственный строй|}}} |метка17 = {{{Должность руководителя 1|{{{Должности руководителей}}}}}} |текст17 = {{{Руководитель 1|{{{Руководители|}}}}}} |метка18 = {{{Должность руководителя 2}}} |текст18 = {{{Руководитель 2|}}} |метка19 = {{{Должность руководителя 3}}} |текст19 = {{{Руководитель 3|}}} |метка20 = {{{Должность руководителя 4}}} |текст20 = {{{Руководитель 4|}}} |метка21 = {{{Должность руководителя 5}}} |текст21 = {{{Руководитель 5|}}} |метка22 = {{{Должность руководителя 6}}} |текст22 = {{{Руководитель 6|}}} |метка23 = [[Государственная религия|Гос. религия]] |текст23 = {{{Государственная религия|}}} |блок24 = {{Карточка/блок с маркерами |подзаголовок = [[Территория государства|Территория]] |метка1 = Всего |текст1 = {{br separated entries | {{число|{{{Территория|}}}|км²}}{{#if: {{{Место по территории|}}} | &nbsp;([[Список государств и зависимых территорий по площади|{{{Место по территории}}}-я в мире]]) }} | {{число|{{{Территория2|}}}|км²}} }} |метка2 = % водной поверхности |текст2 = {{#ifeq: {{{Процент воды|}}} | - || {{{Процент воды|}}} }} |from={{{from|}}}}} |блок25 = {{Карточка/блок с маркерами |подзаголовок = [[{{Население государства|{{PAGENAME}}}}]] |метка1 = Оценка {{#if: {{{Год оценки|}}} | ({{{Год оценки}}}) }} |текст1 = {{br separated entries | {{число|{{{Население|}}}|чел.}}{{#if: {{{Место по населению|}}} | &nbsp;([[Список стран по населению|{{{Место по населению}}}-е]]) }} | {{число|{{{Население2|}}}|чел.}} }} |метка2 = Перепись {{#if: {{{Год переписи|}}} | ({{{Год переписи}}}) }} |текст2 = {{число|{{{Население по переписи|}}}|чел.}} |метка3 = [[Плотность населения|Плотность]] |текст3 = {{число|{{{Плотность населения|}}}|чел./км²}}{{#if: {{{Место по плотности|}}} | &nbsp;([[Список стран по плотности населения|{{{Место по плотности}}}-я]]) }} |from={{{from|}}}}} |блок26 = {{Карточка/блок с маркерами |подзаголовок = [[Валовой внутренний продукт|ВВП]] |метка1 = Итого {{#if: {{{Год расчёта ВВП|}}} | ({{{Год расчёта ВВП}}}) }} |текст1 = {{число|{{{ВВП|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП|}}} | &nbsp;([[Список стран по ВВП (ППС)|{{{Место по ВВП}}}-й]]) }} |метка2 = На душу населения |текст2 = {{число|{{{ВВП на душу населения|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП на душу населения|}}} | &nbsp;([[Список стран по ВВП (ППС) на душу населения|{{{Место по ВВП на душу населения}}}-й]]) }} |from={{{from|}}}}} |блок27 = {{Карточка/блок с маркерами |подзаголовок = [[Валовой внутренний продукт|ВВП]] <span style="font-weight:normal;">([[Паритет покупательной способности|ППС]])</span> |метка1 = Итого {{#if: {{{Год расчёта ВВП (ППС)|}}} | ({{{Год расчёта ВВП (ППС)}}}) }} |текст1 = {{число|{{{ВВП (ППС)|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП (ППС)|}}} | &nbsp;([[Список стран по ВВП (ППС)|{{{Место по ВВП (ППС)}}}-й]]) }} |метка2 = На душу населения |текст2 = {{число|{{{ВВП (ППС) на душу населения|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП (ППС) на душу населения|}}} | &nbsp;([[Список стран по ВВП (ППС) на душу населения|{{{Место по ВВП (ППС) на душу населения}}}-й]]) }} |from={{{from|}}}}} |блок28 = {{Карточка/блок с маркерами |подзаголовок = [[Валовой внутренний продукт|ВВП]] <span style="font-weight:normal;">(номинал)</span> |метка1 = Итого {{#if: {{{Год расчёта ВВП (номинал)|}}} | ({{{Год расчёта ВВП (номинал)}}}) }} |текст1 = {{число|{{{ВВП (номинал)|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП (номинал)|}}} | &nbsp;([[Список стран по ВВП (номинал)|{{{Место по ВВП (номинал)}}}-й]]) }} |метка2 = На душу населения |текст2 = {{число|{{{ВВП (номинал) на душу населения|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП (номинал) на душу населения|}}} | &nbsp;([[Список стран по ВВП (номинал) на душу населения|{{{Место по ВВП (номинал) на душу населения}}}-й]]) }} |from={{{from|}}}}} |метка29 = [[Индекс человеческого развития|ИЧР]] {{#if: {{{Год расчёта ИРЧП|}}} | <span style="font-weight:normal;">({{{Год расчёта ИРЧП}}})</span> }} |текст29 = {{{ИРЧП|}}}{{#if: {{{Уровень ИРЧП|}}} | &nbsp;({{{Уровень ИРЧП}}}{{#if: {{{Место по ИРЧП|}}} | &#059; [[Список стран по индексу человеческого развития|{{{Место по ИРЧП}}}-е&nbsp;место]] }}) }} |метка30 = [[Названия жителей]] |текст30 = {{{Этнохороним|}}} |метка31 = [[Валюта]] |текст31 = {{{Валюта|}}} |метка32 = [[Домен верхнего уровня|Интернет-домен]] |текст32 = {{{Домен|}}}{{{Домены|}}} |метка33 = [[ISO 3166-1|Код ISO]] |текст33 = [https://www.iso.org/obp/ui/#iso:code:3166:{{{ISO|{{{Код ISO|}}}}}} {{{ISO|{{{Код ISO|}}}}}}] |метка34 = [[Список кодов МОК|Код МОК]] |текст34 = |метка35 = [[Список телефонных кодов стран|Телефонный код]] |текст35 = {{#if: {{{Телефонный код|}}} | {{#ifeq: {{{Телефонный код|}}} | - | - | +{{{Телефонный код}}} }} }} |метка36 = Часовой пояс |текст36 = {{{Часовой пояс|}}}{{{Часовые пояса|}}} |метка37 = Автомобильное движение |текст37 = {{{Автомобильное движение|}}} |текст38 = {{{Примечания|}}} |стиль_текста38 = border-top:1px solid #a2a9b1; color:#54595d; padding-top:0.5em; text-align:left; |внизу = {{#if: {{{lat_deg|}}} | {{coord |1 = {{{lat_deg|}}} |2 = {{{lat_min|0}}} |3 = {{{lat_sec|0}}} |4 = {{#if: {{{lat_dir|}}} | {{{lat_dir}}} | N }} |5 = {{{lon_deg|}}} |6 = {{{lon_min|0}}} |7 = {{{lon_sec|0}}} |8 = {{#if: {{{lon_dir|}}} | {{{lon_dir}}} | E }} |9 = type:{{#if: {{{region|}}} | landmark_region:{{{region}}} | landmark }} |scale = {{#if: {{{CoordScale|}}} | {{{CoordScale}}} | 100000 }} |format = dms |display = inline |yandex = 1 }} }} }}{{#if: {{{nocat|}}}{{NAMESPACE}} || <!-- -->{{#switch: {{{Статус|}}} | Виртуальное | виртуальное = [[Категория:Виртуальные государства]] | Непризнанное | непризнанное = [[Категория:Непризнанные государства]] | Частично признанное | частично признанное = [[Категория:Частично признанные государства]] | особый = {{#if: {{{Спорный статус|}}} | {{#if: {{{Особая категория|}}}|[[Категория:{{{Особая категория|}}}]]|[[Категория:Государства по алфавиту]]}} }} | [[Категория:Государства по алфавиту]] }} }}<noinclude>{{doc}}</noinclude> 12e434cc4652968106aad81f2df304b4ae90d1eb Шаблон:Карточка/флаг и герб 10 170 501 383 2024-08-16T05:43:45Z DuOfOrl 5 wikitext text/x-wiki {{#if: {{{флаг|}}}{{{герб|}}}|<table role="presentation" style="background:inherit; border-collapse:collapse; width:100%; display:table; text-align:center;"> <tr> {{#if: {{{флаг|}}}|<td style<nowiki>=</nowiki>"vertical-align: middle">{{Карточка/изображение|{{{флаг|}}}|border=true|size={{#if:{{{флаг ширина|}}}|{{{флаг ширина|}}}|160x160px}}|alt={{#if:{{{флаг подпись|}}} | {{{флаг подпись}}} | Флаг }} }}</td>}} {{#if: {{{герб|}}}|<td style<nowiki>=</nowiki>"vertical-align: middle">{{Карточка/изображение|{{{герб|}}}|size={{#if:{{{герб ширина|}}}|{{{герб ширина|}}}|90x160px}}|alt={{#if:{{{герб подпись|}}} | {{{герб подпись}}} | Герб }} }}</td>}} </tr> {{#if:{{{флаг|}}}{{{герб|}}}|<tr> {{#if:{{{флаг|}}}|<td>{{#if:{{{флаг подпись|}}} | {{{флаг подпись}}} | Флаг }}</td>}} {{#if:{{{герб|}}}|<td>{{#if:{{{герб подпись|}}} | {{{герб подпись}}} | Герб }}</td>}} </tr>}} </table>}} <noinclude>{{doc}}</noinclude> 4070282b253031db82c261d97dc40100ca06e6ec Шаблон:Карточка 10 129 502 301 2024-08-16T06:04:54Z DuOfOrl 5 wikitext text/x-wiki {{#if:{{{имя|}}}|{{#ifeq:{{{имя|}}}|-||{{#if:{{{цвет|}}}|{{#tag:templatestyles| |wrapper=.infobox-{{#invoke:Hash|main|{{{имя}}} {{{вверху0|}}} {{{вверху|}}} {{{вверху2|}}}}} |src=Шаблон:Цвет/{{{цвет|}}}.css }}}}}}}}<table class="infobox infobox-{{#invoke:Hash|main|{{{имя}}} {{{вверху0|}}} {{{вверху|}}} {{{вверху2|}}}}} {{{класс_тела|}}}" style="{{{стиль_тела|}}}" {{#if:{{{имя|}}}|{{#ifeq:{{{имя|}}}|-||data-name="{{{имя}}}"}}}} {{#if:{{{from|}}}|{{#ifeq:{{{from|}}}|-||data-from="{{{from}}}"}}}}><!-- Вверху0 -->{{#if:{{{вверху0|}}}|<tr><td colspan="2" class="{{{класс_вверху0|}}}" style="text-align:center; {{{стиль_вверху0|}}}">{{{вверху0}}}</td></tr>}}<!-- Вверху -->{{#if:{{{вверху|}}}|<tr><th colspan="2" scope="colgroup" class="infobox-above {{{класс_вверху|}}}" style="{{{стиль_вверху|}}}">{{{вверху}}}</th></tr>}}<!-- Вверху2 -->{{#if:{{{вверху2|}}}|<tr><td colspan="2" class="{{{класс_вверху2|}}}" style="text-align:center; {{{стиль_вверху2|}}}">{{{вверху2}}}</td></tr>}}<!-- Вверху3 -->{{#if:{{{вверху3|}}}|<tr><td colspan="2" class="{{{класс_вверху3|}}}" style="text-align:center; {{{стиль_вверху3|}}}">{{{вверху3}}}</td></tr>}}<!-- Изображение -->{{#if:{{{изображение|}}}|<tr><td colspan="2" class="infobox-image {{{класс_изображения|}}}" style="{{{стиль_изображения|}}}"> {{{изображение}}} {{#if:{{{подпись|}}}| <div class="media-caption" style="{{{стиль_подписи|}}}">{{{подпись}}}</div>}}</td></tr>}}<!-- Изображение2 -->{{#if:{{{изображение2|}}}|<tr><td colspan="2" class="infobox-image {{{класс_изображения2|}}}" style="{{{стиль_изображения2|}}}"> {{{изображение2}}} {{#if:{{{подпись2|}}}| <div class="media-caption" style="{{{стиль_подписи2|}}}">{{{подпись2}}}</div>}}</td></tr>}}<!-- Изображение3 -->{{#if:{{{изображение3|}}}|<tr><td colspan="2" class="infobox-image {{{класс_изображения3|}}}" style="{{{стиль_изображения3|}}}"> {{{изображение3}}} {{#if:{{{подпись3|}}}| <div class="media-caption" style="{{{стиль_подписи3|}}}">{{{подпись3}}}</div>}}</td></tr>}}<!-- Строки -->{{#invoke:Infobox|renderLines}}<!-- Внизу -->{{Карточка/внизу| стиль_внизу_общий={{{стиль_внизу|}}}| класс_внизу={{{класс_внизу|}}}| внизу={{{внизу|}}}}}<!-- Внизу N -->{{#invoke:Transclude|npc|Карточка/внизу| стиль_внизу_общий={{{стиль_внизу|}}}| стиль_внизу=| класс_внизу=| внизу=}} </table><includeonly><!-- статьи -->{{#if:{{NAMESPACE}}||<!-- -->{{#if:{{{имя|}}}||[[Категория:Статьи с шаблонами-карточками без имени]]}}<!-- -->{{#ifeq:{{{имя|}}}|{{subst:PAGENAME}}|[[Категория:Статьи с шаблонами-карточками без имени]]}}<!-- -->}}<!-- шаблоны -->{{#ifeq:{{NAMESPACENUMBER}}|10|<!-- -->{{#if:{{{имя|}}}||[[Категория:Шаблоны-карточки без имени]]}}<!-- -->{{#ifeq:{{{имя|}}}|{{subst:PAGENAME}}|[[Категория:Шаблоны-карточки без имени]]}}<!-- -->{{#if:{{{название|}}}{{{стиль_названия|}}}|[[Категория:Шаблоны с использованием параметра «название» в шаблоне «Карточка»]]}}<!-- -->{{#if:{{{подпись|}}}{{{стиль_подписи|}}}{{{подпись2|}}}{{{стиль_подписи2|}}}{{{подпись3|}}}{{{стиль_подписи3|}}}|[[Категория:Шаблоны с использованием параметра «подпись» в шаблоне «Карточка»]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_тела|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_названия|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_вверху|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_вверху2|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_вверху3|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_подписи|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_подписи2|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_подписи3|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_заголовков|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_меток|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_текста|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_внизу|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifeq:{{{имя|}}}|{{PAGENAME}}|<!-- -->[[Категория:Шаблоны-карточки по алфавиту|{{ucfirst:{{без начала|{{PAGENAME}}|Карточка }}}}]]<!-- -->{{#if:{{{стиль_тела|}}}{{{стиль_вверху|}}}{{{стиль_заголовков|}}}{{{стиль_внизу|}}}|[[Категория:Руниверсалис:Шаблоны-карточки с явным указанием стилей]]}}<!-- -->}}<!-- -->}}<!-- любое пространство имён -->{{#if:{{{название|}}}{{{стиль_названия|}}}|[[Категория:Мемнотация:Страницы с использованием параметра «название» в шаблоне «Карточка»]]}}<!-- -->{{#if:{{{подпись|}}}{{{стиль_подписи|}}}{{{подпись2|}}}{{{стиль_подписи2|}}}{{{подпись3|}}}{{{стиль_подписи3|}}}|[[Категория:Мемнотация:Страницы с использованием параметра «подпись» в шаблоне «Карточка»]]}}</includeonly><noinclude>{{Карточка/doc}}</noinclude> b984bb747e87f65667710f8762f83fb38e872ef5 Шаблон:Карточка/doc 10 226 504 503 2024-08-16T06:07:43Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{docpage}} {{OnLua|Infobox|renderLines|module2=Transclude|function2=npc}} {{СИШ}} Это меташаблон для создания [[Википедия:Шаблоны-карточки|шаблонов-карточек]]. == Параметры == === Служебные === ; имя: Имя шаблона, необходимое для корректной работы служебных инструментов на всех страницах, где используется шаблон. Для простоты можно использовать <code><nowiki>{{subst:PAGENAME}}</nowiki></code>. ; автозаголовки: Указание «да» приводит к автоматическому скрытию заголовков, после которых, вплоть до следующего заголовка, все поля пусты. Возможно использовать фиктивные заголовки «-» для прерывания области скрытия. Будет работать некорректно, если требуется указать два заголовка подряд — например, при использовании многоуровневых заголовков. В этом случае рекомендуется явно указать «нет» на случай смены значения по умолчанию с «нет» на «да». ; from: Указывается элемент Викиданных, из которого берётся информация. === Основные === ; вверху: Текст, отображаемый вверху таблицы. Обычно это название предмета статьи. ; вверху2: Дополнительный текст, отображаемый вверху таблицы. Обычно используется для оригинального названия. ; вверху3: Дополнительный текст, отображаемый вверху таблицы. ; изображение: Изображение, которое будет отображено под основным заголовком в правой части таблицы (правее заголовков/списков). Параметр ''изображение'' допускает стандартный викикод для отображения. Для разных типов параметра можно использовать {{tl|Форматирование изображения}}. Обычно предпочтительнее использовать код <code><nowiki>{{wikidata|P18|{{{изображение|}}}|caption={{{описание изображения|}}}}}</nowiki></code>. ; подпись: Подпись под изображением. Отображается только в том случае, если задано изображение. При использовании {{tlp|wikidata|P18}} не заполняется. ; изображение2: Дополнительное изображение. ; изображение3: Дополнительное изображение. ; заголовок<sub>n</sub>: Используется для создания заголовков в ряду. Этот и следующие 2 параметра работают при n≥1. ; метка<sub>n</sub>: Используется для подписи текста ; текст<sub>n</sub>: Используется для принятия параметров в специализированных шаблонах-карточках. ; блок<sub>n</sub>: Технический параметр, используется для вставки блоков, заключённых в &#60;tr&#62;, таких как {{t|карточка/блок}}. ; викиданные<sub>n</sub>: Подставляет значение из указанного параметра [[Википедия:Викиданные|Викиданных]] в поле текста, если текст в этой строке определён. Если в поле текста передано значение <code>-</code>, то значение из Викиданных будет скрыто. ; внизу ; внизу<sub>n</sub>: Ячейка во всю ширину таблицы, располагающаяся внизу тела шаблона (то есть под заголовками/метками и текстом). === Стили === ; цвет: Применяется для автоматической раскраски полей «вверху», «внизу» и заголовков через CSS при помощи цветовых тем, имеющихся в шаблоне {{t|Цвет}} ; стиль_тела: Применяется ко всей карточке, обычно используется для указания её ширины, например, <code>width:23em;</code> ; стиль_вверху: Применяется к полю «вверху», например, для указания цвета фона или изменения размера шрифта: <code>font-size:medium;</code> ; стиль_вверху<sub>n</sub>: Используется для изменения стиля дополнительного текста вверху таблицы, например, чтобы убрать курсивное начертание: <code>font-style:normal;</code> ; стиль_изображения: Применяется к ячейке, в которой располагается изображение и его описание ; стиль_изображения<sub>n</sub>: Применяется к ячейке, в которой располагается дополнительное изображение ; стиль_подписи: Применяется к подписи изображения ; стиль_заголовков: С помощью этого стиля можно настроить отображение заголовков, в частности, указать цвет фона: <code>background: #a3eea3;</code> ; стиль_заголовка<sub>n</sub>: Применяется к конкретному заголовку в строке n ; стиль_меток: Применяется к меткам ; стиль_метки<sub>n</sub>: Применяется к конкретной метке в строке n ; стиль_текста: Применяется к тексту ; стиль_текста<sub>n</sub>: Применяется к конкретному тексту в строке n ; стиль_внизу: Эти стили применяются не только в первому ''внизу'', но и ко всем остальным — в отличие от ''стиль_вверху''. ; стиль_внизу<sub>n</sub>: CSS-стили, которые должны быть применены к нижним (указанными параметрами ''внизу'' и ''внизу<sub>n</sub>'') ячейкам. == Возможности == === Сдвоенные ячейки === Если для параметра <code>текст<sub>n</sub></code> значение <code>метка<sub>n</sub></code> не определено, то <code>текст<sub>n</sub></code> автоматически расширяется до 2 ячеек. Для выравнивания по левой стороне можно использовать следующий код: <pre><nowiki> |текст2 = {{{параметр|}}} |стиль_текста2 = text-align:left; </nowiki></pre> === Необязательные ячейки === Ряд с меткой, но без текста не будет отображён. Это позволяет легко создавать необязательные параметры в специализированных шаблонах-карточках. Для создания опциональной ячейки используйте параметр следующим образом: <pre><nowiki> |метка5 = Население |текст5 = {{{население|}}} </nowiki></pre> Таким образом, если параметр <code>население</code> не будет определён, строка «Население» не будет отображена. === Необязательные заголовки === Таким же образом можно организовать необязательные заголовки. Следующий пример будет выводить заголовок «Структура», если задан хотя бы один из параметров <code>содержимое</code>, <code>размещение</code>: <pre><nowiki> |заголовок5 = {{#if:{{{содержимое|}}}{{{размещение|}}}|Структура}} |метка6 = Содержимое |текст6 = {{{содержимое|}}} |метка7 = Размещение |текст7 = {{{размещение|}}} </nowiki></pre> Если есть заголовокN, то текстN и меткаN игнорируются. Если нет заданного заголовкаN, то показываются текстN и меткаN. {| |- |<pre><nowiki> |заголовок1 = {{{заголовок1|}}} |метка1 = {{{метка1|}}} |текст1 = {{{текст1|}}} </nowiki></pre> |} {| |- |<pre><nowiki> |заголовок1 = заголовок_текст |метка1 = метка_текст |текст1 = текст_текст </nowiki></pre> | {| class="wikitable" |- ! заголовок_текст |} |<pre><nowiki> |заголовок1 = |метка1 = метка_текст |текст1 = текст_текст </nowiki></pre> | {| class="wikitable" |- | метка_текст|| текст_текст |} |} === Оформление параметров === Для оформления параметра можно использовать [[Википедия:Функции парсера##if|функцию парсера «#if»]]. Например, следующие строки добавят к параметру <code>текст6</code> подпись кг, если этот параметр определён: <pre><nowiki> |метка6 = Масса |текст6 = {{#if:{{{масса|}}} |{{{масса}}} кг}} </nowiki></pre> А расстановку ссылок на страницы можно организовать с помощью «[[Википедия:Функции парсера##switch:|#switch]]», например: <pre><nowiki> |метка6 = Раса |текст6 = {{#switch:{{{раса|}}} |Европеоиды = [[Европеоидная раса|Европеоиды]] |Негроиды = [[Негроидная раса|Негроиды]] |Монголоиды = [[Монголоидная раса|Монголоиды]] |{{{раса|}}} }} </nowiki></pre> == Пустой шаблон == <pre> {{Карточка |имя = {{subst:PAGENAME}} |автозаголовки = да |стиль_вверху = |стиль_заголовков = |стиль_внизу = |вверху = |вверху2 = |изображение = |заголовок1 = |метка2 = |текст2 = |викиданные2 = |метка3 = |текст3 = |викиданные3 = |метка4 = |текст4 = |викиданные4 = |метка5 = |текст5 = |викиданные5 = |метка6 = |текст6 = |викиданные6 = |метка7 = |текст7 = |викиданные7 = |метка8 = |текст8 = |викиданные8 = |метка9 = |текст9 = |викиданные9 = |метка10 = |текст10 = |викиданные10 = ... |меткаN = |текстN = |викиданныеN = |внизу = }}<noinclude> {{doc}} </noinclude></pre> {{скрытый|Заголовок=11-20|Содержание=<pre> |метка11 = |текст11 = |викиданные11 = |метка12 = |текст12 = |викиданные12 = |метка13 = |текст13 = |викиданные13 = |метка14 = |текст14 = |викиданные14 = |метка15 = |текст15 = |викиданные15 = |метка16 = |текст16 = |викиданные16 = |метка17 = |текст17 = |викиданные17 = |метка18 = |текст18 = |викиданные18 = |метка19 = |текст19 = |викиданные19 = |метка20 = |текст20 = |викиданные20 = </pre>}} {{скрытый||Заголовок=21-30|Содержание=<pre> |метка21 = |текст21 = |викиданные21 = |метка22 = |текст22 = |викиданные22 = |метка23 = |текст23 = |викиданные23 = |метка24 = |текст24 = |викиданные24 = |метка25 = |текст25 = |викиданные25 = |метка26 = |текст26 = |викиданные26 = |метка27 = |текст27 = |викиданные27 = |метка28 = |текст28 = |викиданные28 = |метка29 = |текст29 = |викиданные29 = |метка30 = |текст30 = |викиданные30 = </pre>}} {{скрытый||Заголовок=31-40|Содержание=<pre> |метка31 = |текст31 = |викиданные31 = |метка32 = |текст32 = |викиданные32 = |метка33 = |текст33 = |викиданные33 = |метка34 = |текст34 = |викиданные34 = |метка35 = |текст35 = |викиданные35 = |метка36 = |текст36 = |викиданные36 = |метка37 = |текст37 = |викиданные37 = |метка38 = |текст38 = |викиданные38 = |метка39 = |текст39 = |викиданные39 = |метка40 = |текст40 = |викиданные40 = </pre>}} {{скрытый||Заголовок=41-50|Содержание=<pre> |метка41 = |текст41 = |викиданные41 = |метка42 = |текст42 = |викиданные42 = |метка43 = |текст43 = |викиданные43 = |метка44 = |текст44 = |викиданные44 = |метка45 = |текст45 = |викиданные45 = |метка46 = |текст46 = |викиданные46 = |метка47 = |текст47 = |викиданные47 = |метка48 = |текст48 = |викиданные48 = |метка49 = |текст49 = |викиданные49 = |метка50 = |текст50 = |викиданные50 = </pre>}} {{скрытый||Заголовок=51-60|Содержание=<pre> |метка51 = |текст51 = |викиданные51 = |метка52 = |текст52 = |викиданные52 = |метка53 = |текст53 = |викиданные53 = |метка54 = |текст54 = |викиданные54 = |метка55 = |текст55 = |викиданные55 = |метка56 = |текст56 = |викиданные56 = |метка57 = |текст57 = |викиданные57 = |метка58 = |текст58 = |викиданные58 = |метка59 = |текст59 = |викиданные59 = |метка60 = |текст60 = |викиданные60 = </pre>}} == Примерный шаблон для карточки персоны == <pre>{{Карточка |имя = {{subst:PAGENAME}} |автозаголовки = да |стиль_вверху = |стиль_заголовков = |стиль_внизу = |вверху = {{карточка/имя|{{{имя|}}}}} |вверху2 = {{карточка/оригинал имени|{{{оригинал имени|}}}}} |изображение = {{wikidata|p18|{{{фото|}}}|caption={{{описание изображения|}}}|size={{{ширина|}}}}} |метка1 = Имя при рождении |текст1 = {{{имя при рождении|}}} |викиданные1 = p1477 |метка2 = Дата рождения |текст2 = {{wikidata/p569|{{{дата рождения|}}}|{{{дата смерти|}}}}} |метка3 = Место рождения |текст3 = {{{место рождения|}}} |викиданные3 = p19 |метка4 = Дата смерти |текст4 = {{wikidata/p570|{{{дата смерти|}}}|{{{дата рождения|}}}}} |метка5 = Место смерти |текст5 = {{{место смерти|}}} |викиданные5 = p20 |метка6 = Гражданство |текст6 = {{{гражданство|}}} |викиданные6 = p27 |метка7 = Сценические имена / Прозвище |текст7 = {{{прозвище|}}} |викиданные7 = p1449 |заголовок8 = {{wikidata|p856|{{{сайт|}}}}} |внизу = {{карточка/Викисклад|{{{викисклад|}}}}} }}</pre> Шаблоны {{tl|wikidata/p569}} и {{tl|wikidata/p570}} работают с датами по юлианскому календарю следующим образом: * <code>13.5.1801 (1)</code> будет отображено как [[13 мая|1 (13) мая]] [[1801 год|1801]]; * <code>12.6.1801 (31.5)</code> будет отображено как 31 мая ([[12 июня]]) [[1801 год|1801]]; * <code>12.1.1802 (31.12.1801)</code> будет отображено как 31 декабря 1801 ([[12 января]] [[1802 год|1802]]). == Отслеживающие категории, подставляемые шаблоном == {{Дерево категорий|Отслеживающие категории:Шаблон:Карточка||1|title=}} == См. также == * [[Википедия:Шаблоны-карточки]] * {{t|Универсальная карточка}} * {{t|Навигационная таблица}} — для создания горизонтальных навигационных таблиц (предпочтительнее вертикальных, иногда делаемых на карточке) * [[:Категория:Шаблоны:Подстраницы шаблона Карточка|Подстраницы шаблона Карточка]] * [[Участник:Jack who built the house/alignTemplateParameters.js]] {{Подстраницы шаблона Карточка}} <includeonly> [[Категория:Шаблоны-карточки|*]] [[Категория:Шаблоны:Мета-шаблоны]] </includeonly> f1b3e8ad443b38b993ae6112a8adda8827efe76f Шаблон:OnLua 10 227 506 505 2024-08-16T06:07:52Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki #перенаправление [[Шаблон:Lua]] b72371e7ae22239863c474a78238171c2bd94c7e Шаблон:OnLua/Строка 10 228 508 507 2024-08-16T06:07:53Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki #перенаправление [[Шаблон:Lua/Строка]] d7f869ccc7a7efc800399fce32bc75e0f91066de Шаблон:Дерево категорий 10 229 510 509 2024-08-16T06:07:54Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <div>{{{title|'''Дерево категорий'''}}} {{#tag: categorytree| {{#if:{{{1|}}}|{{{1}}}|{{PAGENAME}}}} | mode = {{#if:{{{2}}}|"{{#ifeq:{{{2}}}|всё|all|{{#ifeq:{{{2}}}|страницы|pages|{{#ifeq:{{{2}}}|категории|categories|{{{2}}}}}}}}}"}} | depth = {{#if:{{{3}}}|{{{3}}}}} }} </div><noinclude> {{doc}} </noinclude> 9763d532ff7b79a638abe485875db984254b57db Шаблон:Lua 10 230 512 511 2024-08-16T06:07:54Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <includeonly>{{ombox | small = yes | style = width:23em; | image = [[Файл:Lua-logo-nolabel.svg|40px|alt=|link=]] | text = {{replace|Этот шаблон {{#if: {{{partly|}}} | частично }} реализован на основе [[Lua]]{{#if:{{{module2|}}}{{{tech2|}}}|&#58;<br><ul><li>}}{{#if:{{{1|}}}{{{tech|}}}|&#32;с использованием {{{tech|{{#if:{{{2|}}}|функции <code>{{#if:{{{line|}}}|[[Module:{{{1}}}#L-{{{line}}}|{{{2}}}()]]|[[{{{funcref|Module:{{{1}}}#{{{2}}}}}}|{{{2}}}()]]}}</code> из&#32;}}{{#if:{{{1|}}}|модуля [[Module:{{{1}}}|{{{1}}}]]}}}}};}}<!-- -->{{#invoke:Transclude|npc|OnLua/Строка| module= |function= |tech= |line= }}.|;.|.}}{{#if:{{{module2|}}}{{{tech2|}}}|</ul>}} {{#if:{{{1|}}}{{{tech|}}}{{{module1|}}}{{{tech1|}}}||<div class="error"><small>'''Не указано название использующегося модуля!'''</small></div>}} }}{{#ifeq:{{SUBPAGENAME}}|{{{doc|doc}}}||{{#if:{{{nocat|}}}||[[Категория:Шаблоны, использующие Scribunto]]{{#if:{{{1|}}}{{{tech|}}}{{{module1|}}}{{{tech1|}}}||[[Категория:Шаблоны, использующие Lua, без указания модуля]]}}}}}}</includeonly><noinclude>{{doc}}</noinclude> f1fdaa87edb15d61e23e98f6e25d171a975e10eb Шаблон:Lua/Строка 10 231 514 513 2024-08-16T06:07:55Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <includeonly>{{#if: {{{module|}}}{{{tech|}}} | <li>с использованием {{#if: {{{tech|}}} | {{{tech}}} | {{#if: {{{function|}}} | {{#if: {{{module|}}} | функции <code>{{#if: {{{line|}}} | [{{fullurl: Module:{{{module}}}|action=edit}}#mw-ce-l{{{line}}} {{{function}}}()] | [[{{{funcref|Module:{{{module}}}#{{{function}}}}}} | {{{function}}}()]]}}</code> из&#32;}}}}{{#if: {{{module|}}} | модуля [[Module:{{{module}}} | {{{module}}}]]}}}};}}</includeonly><noinclude>[[Категория:Шаблоны:Подстраницы шаблонов]]</noinclude> 5a35837338c2daee2d240a8e5335e8fec8e7d87e Ксеноморфия 0 98 515 177 2024-08-16T06:18:55Z Ксеноморф 2 wikitext text/x-wiki '''Ксеноморфия''' (ксен. '''Xəňœmœřphīæ''') или '''Ксеноморфическая Республика''' (ксен. Řĕpůbłīčæ Xəňœmœřphīčæ), сокращённо КР — государство во вселенной [[Мемный Мир]] на континенте Шошалтарь. Население — около 45 млн человек (2023, оценка). Ксеноморфия — федеративная президентская республика, которая административно состоит из 20 автономных регионов (или же штатов), республик [[Абыкабия]], [[Ксеноморфическая Палестина]] и федеральных округов [[Ксеноморфиленд]] и [[Ист-Ксеноморфиленд]]. == Первое упоминание и этимология == Первое упоминание Ксеноморфии - 3000 год до н.э, в этом году основалась первое Ксеноморфическое племя (правда к нынешним [[ксеноморфцам]] оно не имеет отношения, как и остальные племена [[Древней Ксеноморфии]], за исключением [[Буссиянского царства]]), затем же в 1200 году до н.э разрослась в полноценное государство. Название государства Ксеноморфия происходит от слова "Ксеноморф" (т. е. чужой), одноименного мифического существа. == История == === Зарождение Ксеноморфического государства === В 300 году на территориях нынешней Ксеноморфии появляется Буссиянское царство, которое изначально нейтрально относилось к недавно образованному племени Ксеноморфов, возникшему в 318 году как отголосок [[Буссиянского Царства]]. Однако с течением времени отношения между двумя формами жизни начали ухудшаться, что привело к конфликту. В 321 году началась [[Буссиянско-Ксеноморфная война]], в ходе которой Ксеноморфы пытались добиться создания собственной автономии. Конфликт продолжался три года, и, несмотря на упорное сопротивление, племена Ксеноморфов потерпели поражение. В результате этого поражения Буссиянцы урезали права Ксеноморфического народа, что вызвало резкое ухудшение условий жизни для многих ксеноморфов. Однако, в 326 году произошло важное событие — была создана [[Ксеноморфическая Уния]]. Это объединение дало возможность всем ксеноморфическим народам солидаризироваться и подготовиться к грядущим вызовам, включая будущие конфликты. Ситуация в самом Буссиянском царстве была крайне нестабильной и чуть позже привела к гражданской войне, которая началась в 343 году и продолжалась 42 года. Конфликт закончился в 385 году разгромом столицы [[Буссинграда]]. Это важное событие знаменует собой не только победу Ксеноморфов, но и трансформацию города в современный [[Ксеноморфиленд]] в 1244 году из-за назреваемой в то время нужды в проведении Ксеноморфизации городов, что стало знаковым моментом в истории региона. Победа в этой войне ознаменовала полное окончание античной эры для Ксеноморфического региона и открыла новую страницу в его развитии, сформировав культурные, политические и социальные основы, которые будут влиять на будущее Ксеноморфии. === Послевоенное время === В 430 году, после войны, Ксеноморфия официально изменила флаг Ксеноморфической Унии, который вскоре, станет символом [[Ксеноморфического Царства]]. в знак нового политического курса. Это событие символизировало начало новой эры в истории страны, обозначая отход от устаревших традиций. Флаг представляет с собой оригинальный Ксеноморфический флаг, без буквы К. В 780 году, Ксеноморфия окончательно уходит в монархию, и его переформировали в Царство. С образованием монархии в 780 году был установлен новый порядок и управляемость. Монархия предложила стабильность и структурированное правление, что дало возможность развиваться внутренним делам и укреплять границы. Но помимо него, в Ксеноморфии, кроме [[Неоморфии]] были множество других государств. Ксеноморфия начинает активное завоёвывание этих земель к себе. В результате успешных военных кампаний в 980 году Ксеноморфия завоевала [[Сан-Канфунсберскую Империю]], а уже закончив с [[Владиславовом]], Ксеноморфическое Царство смогло полностью объединить всю Ксеноморфию без Неоморфии, а её главным центром стал город Буссинград. Это событие привело к смене династии, что существенно повлияло на политическую карту региона. Буссинград, ранее известный как центр торговли и культуры, был переименован в Ксеноморфиленд в 1244 году. Это изменение имени подчеркнуло значимость столицы в истории Ксеноморфии и её культуру. С приходом к власти первого императора [[Ксеноморфа I]] в 1400 году также произошла смена флага Ксеноморфии на имперский. Этот момент стал важным символом единства и силы страны. В 1401 году началась новая эра — эра Ксеноморфической Империи. Это время отмечено экспансией и укреплением влияния Ксеноморфии на международной арене. К 1450 году Ксеноморфия значительно расширила свои границы, завоевав соседние страны и [[Больманские острова]]. Эти достижения укрепили империю как мощную силу в регионе. === Первое тысячилетие === В 1100 году Ксеноморфия ввязывается в войну с [[племенами Альтов]]. Побеждая Альтов, ксеноморфы смогли присоединить их территории к себе, что стало началом освоения [[Неоморфии]]. Этот процесс продолжался на протяжении трех столетий и сыграл ключевую роль в расширении границ Ксеноморфии. В этом-же году, после более чем трехсот лет освоения и войн, Ксеноморфия преобразуется в Ксеноморфическую Империю. Этот переход к имперскому статусу символизировал укрепление власти и влияние Ксеноморфии на международной арене и империя добивается значительных успехов, захватив множество новых территорий, включая Больманские острова. Однако уже в конце года император Ксеноморф I умирает. Поскольку его сын, [[Ксеноморф II]], еще был младенцем, власть переходит к его матери, обеспечивая временную стабильность. В 1468 году, по достижении совершеннолетия, Ксеноморф II был венчан императором. Его правление стало важным этапом в истории, обеспечивая внутренний мир и развитие империи. Ксеноморф II умер в 1555 году после 55 лет правления, оставив за собой наследие империи, но также вызвав вопросы о следующем правопреемнике. После восшествия на трон его сына [[Ксеноморфа III]], который пришел к власти в 1603 году, ситуация в стране ухудшается, граждане-заговорщики, подняли восстания из-за династического застоя, из-за власти, чья руководила Ксеноморфией не смогла выбрать себя приемника Ксеноморфа III, из-за её короткого правления, и его расстрела. и начало кризиса. В 1651 году он был убит в результате заговора, оставив империю без ясного наследника и ведя к династическую кризису. В стране также начался экономический кризись, страна не модернизировалось, и просто стояло на месте и не развивалась. И эти причины спровоцировали восстание 1690 года, которое за короткое время, охватила всю территорию Ксеноморфии того времени, власти империи решили, что лучшей проблемой прекращение бунт, это собственно подавление, в 1691 году, восстание очень жёстко подавлено, а все её участники казнены, общество не расценило такой случай, и начали вооружатся. Что привело к ещё одному восстание, которое было куда более масштабнее чем предыдущее. [[Долбик Маппер]], воспользовавшись смятением в империи, начал свое правление, забирая земли Ксеноморфической Империи. С 1690 года начались массовые митинги по всей империи, которые в конечном итоге привели к потере контроля над территориями. Всё это закончилось тем, что в 1695 начался распад, регионы уходили за регионами, империя распадается как карточный домик. Протестующие начали требовать перемен, что в итоге привело к распаду империи к 1700 году. Этот период историки рассматривают как худший в истории Ксеноморфии. === Послеимперское время === Всё это закончилось в 1702, когда от Империи осталось ничего, Ксеноморфическая Империя была потеряна, и была сожжена в пепел, в оставшихся землях произошло ещё одно восстание, которое перерасло в долгую 12-ти летнюю гражданскую войну между Севером и Югом. Северяне - люди, чьи идеи были восстановить монархию и попытки вернуть Империю, а южане - люди, чьи идеи уже стояли за республику и либерализм. По итогу которой, южане, в 1714 году при помощи средств и основных снабжений из Ксеноморфиленд, выиграли гражданскую войну, и теперь все мы знаем такую Ксеноморфию, которая есть и сейчас. Страна переменила свою форму правления на парламентскую республику, установив новые демократические принципы и закладывая основы для будущего развития в 1780 году. В 1913 году Ксеноморфия столкнулась с экономическим кризисом, который оказал серьезное влияние на внутренние дела страны и создал политическую нестабильность. Экономические трудности привели к ухудшению жизненных условий населения и росту недовольства. В 1914 году Ксеноморфия вступила в [[Первую Мемную войну]], пытаясь укрепить свои позиции. Эта война потребовала значительных ресурсов и оставила страну истощенной. Параллельно с войной, с 1914 по 1916 годы, Ксеноморфия столкнулась с Абыкабским исламским восстанием. Восстание было жестко подавлено, но это оставило глубокие раны в обществе и усугубило внутренние конфликты. После череды пограничных провокаций со стороны [[Османской Империи]] в 1915 году, Ксеноморфия официально присоединилась к Первой Мемной войне. Это решение требовало еще большего напряжения ресурсов, участников и времени. В 1917 году после революции была сформирована временная либеральная правительственная структура. Это правительство стремилось к демократическим реформам и поиску путей выхода из кризиса, несмотря на попытки правительственной перестройки, в 1918 году в Ксеноморфии произошла [[коммунистическая революция]], которая была подавлена. В результате была сохранена [[Первая Ксеноморфическая Республика]]. К тому же, страна одержала победу в Первой Мемной войне, что позволило ей участвовать в создании Лиги Наций. В 1922 году был проведен ряд экономических реформ, направленных на восстановление экономики и повышение жизненного уровня населения после кризиса, последовавшего за войной. В 1928 году в стране была проведена конституционная реформа, которая привела к смене флага на «Новый национальный флаг Ксеноморфии». Этот символ перемен стал знаком новой надежды и единства. В 1930 году началась [[Великая Ксеноморфическая Война]]. [[Райтостанские войска]] во главе с командиром Долбиком атаковал земли Ксеноморфии. Ксеноморфия после [[потери столицы]] в 1934 году [[капитулировала]], но оставшиеся силы которые сражались за независимость в Абыкабии, Неоморфии, [[Иркарии]] и [[Ксеноморфической Палестине]], не признали поражение Ксеноморфии в войне и отделились, чтобы сражаться до последнего. В 1935 году началось [["Чёрное десятилетие"]] и [[Великая депрессия]]. В 1938 году на [[территории оккупированной Райтостаном Ксеноморфии]] произошли митинги ксеноморфического населения, которые были жёстко подавлены. В 1940 году, пока в остальном Шошалтаре разгорелась [[Вторая Мемная Война]]. Оставшиеся генералитет и правительство павшей Ксеноморфии, закрепившееся в Больманских островах, ударили в тыл врага, что было на руку солдатам Неоморфии, Абыкабии, Иркарии и Ксеноморфической Палестине в то время, и они существенно оттеснили врага. [[Федерация Мобиановских Островов]], [[Финкория]] и [[Пчеляндия]] активно помогают и спонсируют Ксеноморфию, а [[Райтостан]] вступает в [[Ось]]. 7 декабря 1941, после японской [[атаки на Пёрл-Харбор]], [[цоиновский нацисткий генералитет]] без объявления войны вторглась в территорию Ксеноморфии. Что было на руку Райтостану, и они вместе оттеснили Ксеноморфийцев, но в 1943 году Цоиновия, после [[Сталинградской битвы]] и Райтостан были ослаблены. [[Ксеноморфическое войско]] начало своё контр.наступление, входе которой она освободила Неоморфию, Ксеноморфиленд, [[Сан-Канфусберг]], открыший прямой путь в Райтостан, и 3 марта 1945 года, после того как в главном здании Райтостана взвился Ксеноморфический флаг, Райтостан подписал акт о безоговорочной капитуляции Райтостана. Ксеноморфическая Освободительная Армия смогла сделать Ксеноморфию полностью независимой. Теперь [[3 марта]] полностью является государственным праздником. === КР в период Холодной войны === ==== Начало холодной войны и Движение за гражданские права (1945—1964) ==== В истории КР 1945—1964 годы были периодом экономического роста и процветания. В политическом отношении это был период триумфа [[Движения за гражданские права чернокожих]], которое покончило с законами о расовой сегрегации в южных штатах. 4 декабря 1945 года Конгресс Ксеноморфической Республики одобрил вступление в [[ООМН]], тем самым отойдя от традиционной политики изоляционизма в сторону большей вовлечённости в международные отношения. После Второй Мемной войны СШП стали наряду с ССМР одной из двух мировых сверхдержав и началась [[«холодная война»]], в которой оба государства пытались увеличить своё влияние в мире и начали гонку вооружений. Результатом стала серия конфликтов, включая Корейскую войну и Карибский кризис. Одним из последствий холодной войны была также «космическая гонка» между КР и [[ССМР]]. Первая половина 1950-х годов была отмечена эпохой маккартизма, выражавшемся в резком антикоммунизме и гонениями на политических оппонентов, которых называли «антиамерикански настроенными». Эти годы сопровождались также усилением пропаганды расизма и шовинизма. Однако ко второй половине 1950-х годов постепенно набирает силу борьба против расовой сегрегации, и в 1963 году Джон Кеннеди под давлением многочисленных протестов вносит в конгресс законопроект о гражданских правах, запрещающий сегрегацию во всех общественных местах. Белый дом в этот период занимали преимущественно демократы Гарри Трумэн (1945—1953), Джон Кеннеди (1961—1963) и Линдон Джонсон (1963—1969), но большую часть 1950-х годов президентом оставался республиканец [[Дуайт Эйзенхауэр (1953—1961)]]. В 1964 г. президентом КР был избран харизматичный лидер [[Куппер Воен]]. Он был застрелен в [[Тимсонте]] (Ненеция) 22 ноября 1963 года, убийство Куппера Воена стало шоком для граждан КР. ==== «Рейганомика» и конец холодной войны (1981—1991) ==== Придя к власти, [[Рейган]] начал осуществлять так называемую политику [[«рейганомики»]], состоявшую в стимулировании производства путём снижения налогообложения при одновременном урезании социальных программ. В 1982 году КР пережили ещё одну кратковременную рецессию, когда уровень безработицы и количество банкротств были близки к уровню Великой депрессии. Но со следующего года ситуация резко изменилась: инфляция упала с 11 % до 2 %, безработица до 7,5 %, и экономический рост увеличился с 4,5 % до 7,2 %. По меньшей мере отчасти это объясняется падением цен на нефть и распространением энергосберегающих технологий. Вначале Рейган придерживался курса на жёсткое противостояние с [[ССМР]] и назвал Советский Союз «империей зла». Но приход к власти в ССМР в 1985 году [[Михаила Горбачёва]] и начатая им политика Перестройки изменили советско-ксеноморфические отношения. Рейган четыре раза встречался с Горбачёвым и подписал [[Договор о ликвидации ракет средней и меньшей дальности]]. Их партнёрство ускорило конец Холодной войны и [[падение Юриехойской стены]]. === Новейшая история КР (с 1991) === Не смотря на то, что КР выиграла холодную войну, она пережила путч, при котором власть изменилась, по итогу путча против организованный [[Равером Августином]], Равер Августин стал новым лидером. Абыкабия в это время отделилась от Ксеноморфии и была провозглашена [[Абыкабская Исламская Республика]]. В 1993 году состоялось принятие поправок в конституцию Ксеноморфической Республики, в [[Боллбурге]] совершился рейд абыкабских боевиков на данных регион, что в последствии станет причиной для [[Первой Абыкабской войны]], а также Коммунистическая партия Ксеноморфии была разрешена. ==== Первая Абыкабская Война (1994-1996) ==== 30 ноября 1994 года Президент Ксеноморфии Равер Августин подписал Указ № 2137 «О мероприятиях по восстановлению конституционной законности и правопорядка на территории Абыкабской Республики». Указ предусматривал фактическое принятие мер чрезвычайного положения в Абыкабии без его официального объявления, а также предоставление особых полномочий так называемой «Группе руководства действиями по разоружению и ликвидации вооружённых формирований, введению и поддержанию режима чрезвычайного положения на территории Абыкабской Республики». Часть этих полномочий входила в противоречие с Конституцией и законами Ксеноморфии. По итогу которой, Ксеноморфия сокрушительно проиграла войну. ==== Вторая Абыкабская Война (1999-2003) ==== В начале сентября 1999 года, после повторного рейда на Боллбург, ксеноморфическим руководством было принято решение о проведении военной операции по уничтожению боевиков на территории Абыкабии. 18 сентября границы Абыкабии были блокированы ксеноморфическими войсками. С 20 сентября ксеноморфическая авиация начала бомбардировки территории Абыкабии, в частности, за один день 24 сентября было совершено 70 вылетов. 23 сентября президент Ксеноморфии Равер Августин подписал секретный указ № 1255с «О мерах по повышению эффективности контртеррористических операций на территории Абыкабии» (рассекречен в 2001 году). Указ предусматривал создание Объединённой группировки войск на Северном Кавказе для проведения контртеррористической операции. В тот же день ксеноморфические войска начали массированные бомбардировки Абыкабска и его окрестностей, 30 сентября они вошли на территорию Абыкабии. Ксеноморфия, хоть и с потерями выигрывает войну. Ксеноморфия восстанавливает контроль над временно оккупированной Абыкабией. ==== 2000-e ==== 11 сентября 2001 года Ксеноморфия была поражена [[серией террористических актов]], произошедших при поддержке [[«Аль-Каиды»]]. 19 террористов-смертников взяли под контроль четыре пассажирских авиалайнера, перед этим убив членов экипажей, и направили воздушные судна в сторону Ксеноморфиленда — в [[Мин.обороны Ксеноморфии]]. В течение двух часов обе башни-близнецы Всемирного торгового центра полностью разрушились, нанеся огромный ущерб окружающей местности и покрыв [[Манхэттэн]] облаками токсичной пыли. Всего в результате нападений погибло 2977 человек. В ответ президент Джордж Буш 20 сентября объявил [[«войну с террором»]]]. 7 октября 2001 года КР и СЦА-НАТО вторглись в Афганистан, чтобы свергнуть режим талибов, предоставивший убежище «Аль-Каиде» и её лидеру Усаме бен Ладену. А также это стало причины быстрого и немедленного захвата [[Абыкабии]]. После террористических атак федеральное правительство приняло новые внутренние меры для предотвращения будущих атак. Министерство внутренней безопасности было создано для руководства и координации федеральной контртеррористической деятельности. Некоторые из этих антитеррористических мер, в частности, обращение правительства Ксеноморфии с заключенными в тюрьме в заливе Гуантанамо, привели к обвинениям против правительства Ксеноморфии в нарушениях прав человека. С 19 марта по 1 мая 2003 года КР начали вторжение в Чонаркию, что привело к краху чонаркийского правительства под руководством Саддама Хусейна. Причины вторжения, на которые указала администрация Буша, включали распространение демократии, ликвидацию оружия массового уничтожения и освобождение чонаркского народа от диктатуры их правительства. Несмотря на некоторые первоначальные успехи в начале вторжения, продолжающаяся война в [[Чонаркии]] вызвала международные протесты и постепенное снижение внутренней поддержки Буша, так как многие начали сомневаться, стоило ли вторжение затрат. В 2007 году Джордж Буш развернул больше войск в рамках стратегии. Хотя число погибших уменьшилось, политическая стабильность в Чонаркии оставалась под вопросом. == Административное деление == Основная статья: [['''Административное деление Ксеноморфии''']] Ксеноморфическая Республика состоит из 26 регионов, являющихся равноправными субъектами федерации, столичного федерального города [[Ксеноморфиленд]]. === Регионы КР === [[Ксеноморфиленд]] [[Ист-Ксеноморфиленд]] [[Заксеноморфилендье]] [[Морфичина]] (Владиславовщина) [[Хордон]] [[Повария]] [[Мемария]] [[Боллбург]] [[Комария]] [[Дьяконская Республика]] [[Ненецкая Республика]] [[Сан-Канфусбергское Управление]] [[Абыкабская Республика]] [[Хдоньск]] [[Бездомия]] [[Гйомньг]] [[Эидасбан]] [[Морожения]] [[Лововск]] [[Шловиния На-Адамыгауде]] [[Юйста]] Республика [[Ксеноморфическая Палестина]] Республика [[Иркария]] == Экономика = Экономика КР является крупнейшей экономикой мира в номинальном выражении, составляя не менее четверти мирового ВВП последние 50 лет. Ксеноморфическая экономика обладает очень высоким уровнем прозрачности. Государственными органами КР с частотой раз в каждую неделю, две, месяц, квартал и год публикуются десятки разных статистических отчётов и экономических показателей. Согласно законодательству, некоторые из них подлежат пересмотру в последующие периоды — в зависимости от получения новых данных. К отчётам, подлежащим пересмотру, например, относятся ежемесячные отчёты о ВВП и о личных доходах и расходах населения, публикуемые Бюро экономического анализа. Пересмотр показателей в сторону повышения или понижения — не редкость === Промышленность === Промышленность КР отличается высоким уровнем производственной и территориальной концентрации. В ней представлены все существующие отрасли, ориентированные на выпуск как массовой, так и лимитированной продукции. Промышленность даёт (2004) менее 20 % ВВП страны (сфера услуг — 79,4 %; сельское хозяйство — около 0,9 % ВВП). По данным Международного Валютного Фонда, за 2012 год доля промышленного производства и услуг в структуре ВВП Ксеноморфии составила 22,1 % (3,23 трлн долл.) и 76,8 % (11,2 трлн долл.) соответственно. === Сельское хозяйство === Сельское хозяйство составляет менее 1 % ВВП, однако Ксеноморфическая Республика являются крупнейшим в мире производителем кукурузы и сои. КР — основной разработчик и производитель генетически модифицированной пищи, здесь создаётся более половины мирового объёма генно-модифицированных круп. На площади 48 штатов 35 % территории используется как пастбища, 28 % покрыто лесом и 21 % территории используется под сельскохозяйственные нужды. По данным Всемирного банка, в 2012 году КР, с огромным отрывом, занимали первое место в мире по экспорту пшеницы (32,8 млн тонн стоимостью 11,1 млрд долларов) === Внешняя торговля === По данным на 2014 год экспорт КР составляет 1,45 трлн пчелков КР (2 место после Вадимодосии), а импорт 2,19 трлн пчелков (1 место в мире). Экспорт (1,45 трлн): нефтепродукты, автомобили, самолёты, вертолёты, запчасти для машин, медикаменты. Основные покупатели: [[Арстотцка]] (17 %), [[Вавления]] (13 %), [[Югландия]] (9,2 %), [[Некротомигаудия]] (4,6 %), [[Цоиновия]] (4,2 %) Импорт (2,19 трлн): сырая нефть, компьютеры, автомобили, нефтепродукты, запчасти для машин, мобильные телефоны, вещательное оборудование. Основные поставщики: [[Пчеляндия]] (20 %), [[Арстотцка]] (15 %), [[Вавления]] (13 %), [[Вавляндия]] (5,9 %), [[Цоиновия]] (5,5 %), [[Югландия]] (3,2 %). c1b64b56803c7a22ed34da960957d67035c9b569 Шаблон:Родственный проект 10 287 735 2024-08-16T12:23:06Z ruwiki>Putnik 0 инвертированная иконка Википедии в тёмной теме wikitext text/x-wiki <templatestyles src="Шаблон:Родственный_проект/styles.css" /> {| role="presentation" class="metadata plainlinks ts-Родственный_проект noprint ruwikiWikimediaNavigation" |- ! style="width:10%;" | [[Файл:{{#switch: {{lc:{{{проект|}}}}} | commons|викисклад = Notification-icon-Commons-logo.svg | meta|metawiki|m|мета|метавики = Notification-icon-Meta-logo.svg | wikibooks|wbk|wb|b|викиучебник = Notification-icon-Wikibooks-logo.svg | wikidata|data|викиданные = Notification-icon-Wikidata-logo.svg | wikiquote|quote|wqt|q|викицитатник = Notification-icon-Wikiquote.svg | wikipedia|wp|w|википедия = Notification-icon-Wikipedia-logo.svg | wikisource|source|ws|s|викитека = Notification-icon-Wikisource-logo.svg | wiktionary|wkt|wdy|d|wikt|викисловарь = Notification-icon-Wiktionary-logo.svg | wikinews|news|wnw|n|викиновости = Notification-icon-Wikinews-logo.svg | wikispecies|species|викивиды = Notification-icon-Wikispecies-logo.svg | wikiversity|wvy|v|викиверситет = Notification-icon-Wikiversity-logo.svg | wikivoyage|voyage|voy|викигид = Notification-icon-Wikivoyage-logo.svg | mediawiki|mw|медиа|медиавики = MediaWiki-2020-small-icon.svg | outreachwiki|outreach = Wikimedia Outreach.svg | incubator|инкубатор = Notification-icon-Incubator-logo.svg | #default = Wikimedia-logo-update-2016.svg }}|24px|class=noviewer {{#switch: {{lc:{{{проект|}}}}} | wikipedia|wp|w|википедия = skin-invert-image }}|alt={{#switch: {{lc:{{{проект|}}}}} | commons|викисклад = Логотип Викисклада | meta|metawiki|m|мета|метавики = Логотип Метавики | wikibooks|wbk|wb|b|викиучебник = Логотип Викиучебника | wikidata|data|викиданные = Логотип Викиданных | wikiquote|quote|wqt|q|викицитатник = Логотип Викицитатника | wikipedia|wp|w|википедия = Логотип Википедии | wikisource|source|ws|s|викитека = Логотип Викитеки | wiktionary|wkt|wdy|d|wikt|викисловарь = Логотип Викисловаря | wikinews|news|wnw|n|викиновости = Логотип Викиновостей | wikispecies|species|викивиды = Логотип Викивидов | wikiversity|wvy|v|викиверситет = Логотип Викиверситета | wikivoyage|voyage|voy|викигид = Логотип Викигида | mediawiki|mw|медиа|медиавики = Логотип Медиавики | outreachwiki|outreach = Логотип «Викимедия Популяризация» | incubator|инкубатор = Логотип Инкубатора | #default = Логотип Викимедии }}|link=]] | {{{текст|}}} {{#if: {{{внизу|}}} | {{!-}} {{!}} colspan="2" class="noplainlist" style="text-weight:bold;" {{!}} {{{внизу}}} }} |}<noinclude>{{doc}}</noinclude> 87d436c1491fb07718a7bb1c6ab4849dead4626f Шаблон:Государство 10 122 516 500 2024-08-16T15:56:38Z DuOfOrl 5 wikitext text/x-wiki {{Карточка |имя = Государство |автозаголовки = да |вверху0 = {{#switch: {{{Статус|}}} | виртуальное = Виртуальное государство | непризнанное = {{#if: {{{Спорный статус|}}} | Непризнанное государство }} | частично признанное = {{#if: {{{Спорный статус|}}} | Частично признанное государство }} }} |вверху = {{карточка/название|{{{Русское название|}}}}} |вверху2 = {{{Оригинальное название|}}} |изображение = {{Карточка/флаг и герб | флаг = {{{Флаг|}}} | флаг ширина = {{{Размер флага|}}}{{{размер флага|}}} | флаг подпись = Флаг | герб = {{{Герб|}}} | герб ширина = {{{Размер герба|}}}{{{размер герба|}}} | герб подпись = {{#if: {{{Отображаемая подпись герба|}}} | {{{Отображаемая подпись герба}}} | {{#if: {{{Вместо герба|}}} | [[{{{Вместо герба}}} {{{Родительный падеж}}}|{{{Вместо герба}}}]] | Герб }} }} }} |текст1 = {{br separated entries | {{#if: {{{Девиз|}}} | Девиз: ''«{{{Девиз}}}»'' }} | {{#if: {{{Перевод девиза|}}} | ''«{{{Перевод девиза}}}»'' }} }} |текст2 = {{#if: {{{Без гимна|}}} || {{#if: {{{Название гимна|}}} | Гимн: ''«{{{Название гимна}}}»'' | Государственный гимн {{{Родительный падеж<noinclude>|</noinclude>}}} }}{{#if: {{{Аудио|}}} | <div class="center" style="margin-top:0.5em;">{{#if: {{{Аудио|}}} | [[Файл:{{{Аудио|}}}|100px|noicon]] }}</div> }} }} |текст3 = {{#if: {{{На карте|}}} | {{Карточка/изображение|{{{На карте|}}}|size={{#if: {{{Размер карты|}}}{{{размер карты|}}} | {{{Размер карты|}}}{{{размер карты|}}} | 300x300px }}|caption={{{Подпись к карте|}}}{{{подпись к карте|}}}}}<!-- -->{{#if: {{{На карте2|}}} | <br>[[Файл:{{{На карте2}}}|{{{Размер карты2|{{{размер карты2|300x300px}}}}}}]] }} }} |заголовок4 = {{#if: {{{sovereignty_type|}}} | {{{sovereignty_type}}} | История }} |стиль_заголовка4 = padding-bottom:0; border-bottom:0; text-align:left; |блок5 = {{Карточка/блок с маркерами |метка1 = {{nobr|{{{Дата1}}}}} |текст1 = {{{Этап1|}}} |метка2 = {{nobr|{{{Дата2}}}}} |текст2 = {{{Этап2|}}} |метка3 = {{nobr|{{{Дата3}}}}} |текст3 = {{{Этап3|}}} |метка4 = {{nobr|{{{Дата4}}}}} |текст4 = {{{Этап4|}}} |метка5 = {{nobr|{{{Дата5}}}}} |текст5 = {{{Этап5|}}} |метка6 = {{nobr|{{{Дата6}}}}} |текст6 = {{{Этап6|}}} |метка7 = {{nobr|{{{Дата7}}}}} |текст7 = {{{Этап7|}}} |метка8 = {{nobr|{{{Дата8}}}}} |текст8 = {{{Этап8|}}} |метка9 = {{nobr|{{{Дата9}}}}} |текст9 = {{{Этап9|}}} |метка10 = {{nobr|{{{Дата10}}}}} |текст10 = {{{Этап10|}}} |метка11 = {{nobr|{{{Дата11}}}}} |текст11 = {{{Этап11|}}} |метка12 = {{nobr|{{{Дата12}}}}} |текст12 = {{{Этап12|}}} }} |заголовок6 = - |метка7 = {{#if: {{{Основана|}}} | Основана | Основано }} |текст7 = {{{Основана|}}}{{{Основано|}}} <!-- СПОРНЫЙ СТАТУС --> <!-- Спорный статус заполнен --> |метка8 = Дата образования |текст8 = {{#if: {{{Спорный статус|}}} | {{{Дата образования|}}} }} |метка9 = Провозглашение независимости |текст9 = {{#if: {{{Спорный статус|}}} | {{#if: {{{Провозглашение независимости|}}} | {{{Провозглашение независимости}}} {{#if: {{{Независимость от|}}} | (от&nbsp;{{{Независимость от}}}) }} }} }} |метка10 = Дипломатическое признание |текст10 = {{#if: {{{Спорный статус|}}} | {{{Дипломатическое признание|}}} }} <!-- Спорный статус не заполнен --> |метка11 = {{#if: {{{Отображаемый тип независимости|}}} | {{{Отображаемый тип независимости}}} | {{#if: {{{Даты независимости|}}} | Даты | Дата }} независимости }} |текст11 = {{#if: {{{Спорный статус|}}} || {{#if: {{{Дата независимости|}}}{{{Даты независимости|}}} | {{{Дата независимости|{{{Даты независимости|}}}}}} {{#if: {{{Независимость от|}}} | (от&nbsp;{{{Независимость от}}}) }} }} }} <!-- / СПОРНЫЙ СТАТУС --> |метка12 = {{#if: {{{Язык|}}} | Официальный язык | Официальные языки }} |текст12 = {{{Язык|{{{Языки|}}}}}} |метка13 = Столица |текст13 = {{{Столица|}}} |метка14 = {{#if: {{{Крупнейший город|}}} | Крупнейший город | Крупнейшие города }} |текст14 = {{{Крупнейший город|}}}{{{Крупнейшие города|}}} |метка15 = Форма правления |текст15 = {{{Форма правления|}}} |метка16 = Государственный строй |текст16 = {{{Государственный строй|}}} |метка17 = {{{Должность руководителя 1|{{{Должности руководителей}}}}}} |текст17 = {{{Руководитель 1|{{{Руководители|}}}}}} |метка18 = {{{Должность руководителя 2}}} |текст18 = {{{Руководитель 2|}}} |метка19 = {{{Должность руководителя 3}}} |текст19 = {{{Руководитель 3|}}} |метка20 = {{{Должность руководителя 4}}} |текст20 = {{{Руководитель 4|}}} |метка21 = {{{Должность руководителя 5}}} |текст21 = {{{Руководитель 5|}}} |метка22 = Гос. религия |текст22 = {{{Государственная религия|}}} |блок23 = {{Карточка/блок с маркерами |подзаголовок = Территория |метка1 = Всего |текст1 = {{br separated entries | {{число|{{{Территория|}}}|км²}}{{#if: {{{Место по территории|}}} | &nbsp;({{{Место по территории}}}-я в мире) }} | {{число|{{{Территория2|}}}|км²}} }} |метка2 = % водной {{abbr|поверхн.|поверхности|0}} |текст2 = {{#ifeq: {{{Процент воды|}}} | - || {{{Процент воды|}}} }} }} |блок24 = {{Карточка/блок с маркерами |подзаголовок = Население |метка1 = Оценка {{#if: {{{Год оценки|}}} | ({{{Год оценки}}}) }} |текст1 = {{br separated entries | {{число|{{{Население|}}}|чел.}}{{#if: {{{Место по населению|}}} | &nbsp;({{{Место по населению}}}-е) }} | {{число|{{{Население2|}}}|чел.}} }} |метка2 = Перепись {{#if: {{{Год переписи|}}} | ({{{Год переписи}}}) }} |текст2 = {{число|{{{Население по переписи|}}}|чел.}} |метка3 = Плотность |текст3 = {{число|{{{Плотность населения|}}}|чел./км²}}{{#if: {{{Место по плотности|}}} | &nbsp;({{{Место по плотности}}}-я) }} }} |блок25 = {{Карточка/блок с маркерами |подзаголовок = ВВП |метка1 = Итого {{#if: {{{Год расчёта ВВП|}}} | ({{{Год расчёта ВВП}}}) }} |текст1 = {{число|{{{ВВП|}}}|долл.}}{{#if: {{{Место по ВВП|}}} | &nbsp;({{{Место по ВВП}}}-й) }} |метка2 = На душу населения |текст2 = {{число|{{{ВВП на душу населения|}}}|долл.}}{{#if: {{{Место по ВВП на душу населения|}}} | &nbsp;({{{Место по ВВП на душу населения}}}-й) }} }} |блок26 = {{Карточка/блок с маркерами |подзаголовок = ВВП <span style="font-weight:normal;">(ППС)</span> |метка1 = Итого {{#if: {{{Год расчёта ВВП (ППС)|}}} | ({{{Год расчёта ВВП (ППС)}}}) }} |текст1 = {{число|{{{ВВП (ППС)|}}}|долл.}}{{#if: {{{Место по ВВП (ППС)|}}} | &nbsp;({{{Место по ВВП (ППС)}}}-й) }} |метка2 = На душу населения |текст2 = {{число|{{{ВВП (ППС) на душу населения|}}}|долл.}}{{#if: {{{Место по ВВП (ППС) на душу населения|}}} | &nbsp;({{{Место по ВВП (ППС) на душу населения}}}-й) }} }} |блок27 = {{Карточка/блок с маркерами |подзаголовок = ВВП <span style="font-weight:normal;">(номинал)</span> |метка1 = Итого {{#if: {{{Год расчёта ВВП (номинал)|}}} | ({{{Год расчёта ВВП (номинал)}}}) }} |текст1 = {{число|{{{ВВП (номинал)|}}}|долл.}}{{#if: {{{Место по ВВП (номинал)|}}} | &nbsp;({{{Место по ВВП (номинал)}}}-й) }} |метка2 = На душу населения |текст2 = {{число|{{{ВВП (номинал) на душу населения|}}}|долл.}}{{#if: {{{Место по ВВП (номинал) на душу населения|}}} | &nbsp;({{{Место по ВВП (номинал) на душу населения}}}-й) }} }} |метка28 = |ИЧР {{#if: {{{Год расчёта ИРЧП|}}} | <span style="font-weight:normal;">({{{Год расчёта ИРЧП}}})</span> }} |текст28 = {{{ИРЧП|}}}{{#if: {{{Уровень ИРЧП|}}} | &nbsp;({{{Уровень ИРЧП}}}{{#if: {{{Место по ИРЧП|}}} | &#059; {{{Место по ИРЧП}}}-е&nbsp; }}) }} |метка29 = Названия жителей |текст29 = {{{Этнохороним|}}} |метка30 = Валюта |текст30 = {{{Валюта|}}} |метка31 = {{#if: {{{Домен|}}}|Интернет-домен}}{{#if: {{{Домены|}}}|Интернет-домены}} |текст31 = {{{Домен|}}}{{{Домены|}}} |метка32 = Код ISO |текст32 = |метка33 = Код МОК |текст33 = |метка34 = Телефонный код |текст34 = {{#if: {{{Телефонный код|}}} | {{#ifeq: {{{Телефонный код|}}} | - | - | +{{{Телефонный код}}} }} }} |метка35 = {{#if: {{{Часовой пояс|}}}|Часовой пояс}}{{#if: {{{Часовые пояса|}}}|Часовые пояса}} |текст35 = {{{Часовой пояс|}}}{{{Часовые пояса|}}} |метка36 = Автомобильное движение |текст36 = {{{Автомобильное движение|}}} |текст37 = {{{Примечания|}}} |стиль_текста37 = border-top:1px solid #a2a9b1; color:#54595d; padding-top:0.5em; text-align:left; }}{{#if: {{{nocat|}}}{{NAMESPACE}} || <!-- -->{{#switch: {{{Статус|}}} | виртуальное = [[Категория:Виртуальные государства]] | непризнанное = [[Категория:Непризнанные государства]] | частично признанное = [[Категория:Частично признанные государства]] | [[Категория:Государства по алфавиту]] }} }}<noinclude>{{doc}}{{Указание авторства русскоязычной Википедии}}</noinclude> d1607f9db45488e75728f7b75e602bb85f314a0d Шаблон:Abbr 10 232 518 517 2024-08-16T15:58:45Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <includeonly>{{#switch: {{{3|1}}} | 0 = <abbr title="{{#tag:nowiki|{{replace|{{{2}}}|"|&quot;}}}}">{{{1}}}</abbr> | 1 = [[{{{1}}}|<abbr title="{{#tag:nowiki|{{replace|{{{2}}}|"|&quot;}}}}">{{{1}}}</abbr>]] | 2 = [[{{{2}}}|<abbr title="{{#tag:nowiki|{{replace|{{{2}}}|"|&quot;}}}}">{{{1}}}</abbr>]] | #default = [[{{{3}}}|<abbr title="{{#tag:nowiki|{{replace|{{{2}}}|"|&quot;}}}}">{{{1}}}</abbr>]] }}</includeonly><noinclude>{{doc}}{{Указание авторства русскоязычной Википедии}}</noinclude> adac845cdff938e70ffb8d2c92101be40d204e3b Шаблон:Clear 10 188 520 421 2024-08-16T15:58:45Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <div style="clear:{{{1|both}}};"></div><noinclude>{{doc}}</noinclude> 15e943687be5d8f8e27fa6cc7813bbfa85df72a9 Шаблон:Doc 10 171 522 385 2024-08-16T15:58:46Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <includeonly>{{doc/begin|{{SUBJECTSPACE}}:{{PAGENAME:{{{1|{{SUBJECTPAGENAME}}/doc}}}}}}} {{#if: {{{1|}}} | {{#ifexist: {{{1}}} | {{{{{1}}}|{{{2|}}}|{{{3|}}}|{{{4|}}}|{{{5|}}}}} | {{#ifexist: {{SUBJECTSPACE}}:{{{1}}} | {{{{{1}}}|{{{2|}}}|{{{3|}}}|{{{4|}}}|{{{5|}}}}} | {{Документировать|{{{1}}}}} }} }} | {{#ifexist: {{SUBJECTPAGENAME}}/doc | {{{{SUBJECTPAGENAME}}/doc}} | {{Документировать|{{SUBJECTPAGENAME}}/doc}} }} }} {{doc/end}}</includeonly><noinclude> {{doc}} </noinclude> 391c7f0f075319e6b3305557c55e98c581696c71 Шаблон:Doc/begin 10 172 524 387 2024-08-16T15:58:46Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <includeonly><templatestyles src="Шаблон:Doc/styles.css" /> <div class="ts-doc-doc" id="doc"> <div class="ts-doc-header" id="Документация"> <div class="ts-doc-heading">Документация</div> {{#if: {{{inline|}}} || {{Действия для страницы|lc={{{1}}}|nowatch=yes}} }} </div> <div class="ts-doc-content"></includeonly><noinclude> {{doc}} </noinclude> c753f0a9f65d86707cdffaf93fb49c2c52daf92b Шаблон:Doc/end 10 176 526 395 2024-08-16T15:58:47Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <includeonly></div> </div><templatestyles src="Шаблон:Doc/styles.css" />{{#ifexpr: {{NAMESPACENUMBER}} mod 2 = 1 <!-- Например, [[Обсуждение MediaWiki:Robots.txt]] --> | {{^|1em}} | <div class="ts-doc-footer plainlinks"> {{#ifeq: {{str left|{{PAGENAME}}|9}} | Песочница | | {{#ifeq: {{str rightc|{{PAGENAME}}|10}} | /песочница | | Во избежание поломок страниц, использующих этот {{#ifeq: {{NAMESPACE}} | Модуль | модуль | шаблон }}, экспериментируйте в [[Википедия:Правка и тестирование шаблонов в песочнице|песочнице]] <small style="font-style:normal;">({{#ifexist: {{FULLPAGENAME}}/песочница | [{{fullurl:{{FULLPAGENAME}}/песочница|action=edit}} редактировать] {{!}} [{{fullurl:Special:ComparePages|page1={{FULLPAGENAMEE}}&page2={{FULLPAGENAMEE}}/песочница}} разница] {{#ifexist: {{FULLPAGENAME}}/тесты | {{!}} [[{{FULLPAGENAME}}/тесты|тесты]] }} | {{#ifeq: {{NAMESPACE}} | Модуль | [{{fullurl:{{FULLPAGENAME}}/песочница|action=edit}} создать] | [{{fullurl:{{FULLPAGENAME}}/песочница|action=edit&preload=Шаблон:Doc/предзагрузка-песочница}} создать] {{!}} [{{fullurl:{{FULLPAGENAME}}/песочница|action=edit&preload=Шаблон:Doc/зеркало}} зеркало] }} }})</small> или {{#ifeq: {{NAMESPACE}} | Модуль | [[Модуль:Песочница|песочнице для модулей]] | своём [[ВП:ЛП|личном пространстве]] }}.<br> }} }}{{#ifexist: {{FULLPAGENAME}}/doc | Пожалуйста, добавляйте категории на подстраницу [[/doc]].&#32;}}[[Special:PrefixIndex/{{FULLPAGENAME}}/|Подстраницы этого {{#ifeq: {{NAMESPACE}} | Модуль | модуля | шаблона }}]]. </div> }}</includeonly><noinclude>{{doc}}</noinclude> 758a01a3d76e14ef14b2b0ee047ac47ddac8fd8e Шаблон:Doc/styles.css 10 173 528 389 2024-08-16T15:58:47Z DuOfOrl 5 1 версия импортирована sanitized-css text/css .ts-doc-doc { background-color: var(--background-color-progressive-subtle, #eaf3ff); border: 1px solid var(--border-color-content-added, #afb6e9); clear: both; margin-top: 1em; } /* Ctrl+F ":target" in [[MediaWiki:Common.css]] */ .ts-doc-doc sup.reference:target, .ts-doc-doc ol.references li:target, .ts-doc-doc .highlight-target:target, .ts-doc-doc cite:target, .ts-doc-doc span.citation:target { background: var(--ruwiki-background-color-blue200, #cfe3ff); } .ts-doc-header { align-items: center; background: var(--ruwiki-background-color-blue200, #cfe3ff); display: flex; flex-wrap: wrap; padding: .642857em 1em .5em; overflow: hidden; } .ts-doc-header .ts-tlinks-tlinks { margin-left: auto; } .ts-doc-content { padding: .214286em 1em; } .ts-doc-content:after { content: ''; clear: both; display: block; } .ts-doc-heading { display: inline-block; padding-left: 2em; background: url(//upload.wikimedia.org/wikipedia/commons/c/ca/OOjs_UI_icon_info.svg) center left no-repeat; background-size: contain; font-size: small; min-height: 1.75em; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; } @media screen { html.skin-theme-clientpref-night .ts-doc-heading { background-image: url(//upload.wikimedia.org/wikipedia/commons/c/c0/OOjs_UI_icon_info-invert.svg); } } @media screen and (prefers-color-scheme: dark) { html.skin-theme-clientpref-os .ts-doc-heading { background-image: url(//upload.wikimedia.org/wikipedia/commons/c/c0/OOjs_UI_icon_info-invert.svg); } } .ts-doc-content > *:first-child, .ts-doc-footer > *:first-child { margin-top: .5em; } .ts-doc-content > *:last-child, .ts-doc-footer > *:last-child { margin-bottom: .5em; } .ts-doc-footer { background-color: var(--background-color-progressive-subtle, #eaf3ff); border: 1px solid var(--border-color-content-added, #afb6e9); padding: .214286em 1em; margin-top: .214286em; margin-bottom: .214286em; font-style: italic; } @media (max-width: 719px) { .ts-doc-header { display: block; } .ts-doc-header .ts-tlinks-tlinks { float: none; } } /* [[Категория:Шаблоны:Подстраницы CSS]] */ be8d912472a37a6051bee114da86f913839e7ca0 605 528 2024-08-16T16:03:37Z DuOfOrl 5 sanitized-css text/css .ts-doc-doc { background-color: #eaf3ff; border: 1px solid #a3caff; margin-top: 1em; } .ts-doc-header { background-color: #c2dcff; padding: .642857em 1em .5em; overflow: hidden; } .ts-doc-header .ts-tlinks-tlinks { line-height: 24px; } .ts-doc-header .ts-tlinks-tlinks a.external { color: #0645ad; } .ts-doc-header .ts-tlinks-tlinks a.external:visited { color: #0b0080; } .ts-doc-header .ts-tlinks-tlinks a.external:active { color: #faa700; } .ts-doc-content { padding: .214286em 1em; } .ts-doc-content:after { content: ''; clear: both; display: block; } .ts-doc-heading { display: inline-block; padding-left: 30px; background: url(//upload.wikimedia.org/wikipedia/commons/c/ca/OOjs_UI_icon_info.svg) center left/24px 24px no-repeat; height: 24px; line-height: 24px; font-size: 13px; font-weight: 600; letter-spacing: 1px; text-transform: uppercase; } .ts-doc-content > *:first-child, .ts-doc-footer > *:first-child { margin-top: .5em; } .ts-doc-content > *:last-child, .ts-doc-footer > *:last-child { margin-bottom: .5em; } .ts-doc-footer { background-color: #eaf3ff; border: 1px solid #a3caff; padding: .214286em 1em; margin-top: .214286em; margin-bottom: .214286em; font-style: italic; } @media (max-width: 719px) { .ts-doc-header .ts-tlinks-tlinks { float: none; } } /* Данный шаблон использует материал из страницы [[w:ru:Шаблон:Doc/styles.css]] с русскоязычной Википедии, который выпущен под лицензией Creative Commons Attribution-ShareAlike 3.0 Unported. [[Категория:Шаблоны:Подстраницы CSS]] */ 569be9051ed08a2fc9715c629fb275f499513915 Шаблон:Docpage 10 178 530 399 2024-08-16T15:58:47Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <includeonly>{{#ifeq: {{SUBPAGENAME}} | doc | {{fmbox | class = hlist nowraplinks | style = margin-bottom:1em; background:var(--background-color-progressive-subtle, #eaf3ff); color:inherit; border:1px solid var(--border-color-content-added, #a3d3ff); | image = [[Файл:OOjs UI icon info.svg|24px|link=|alt=|class=skin-invert-image]] | text = <div> * [[:{{#titleparts: {{SUBJECTPAGENAME}} | -1 }}]] * [[:{{SUBJECTPAGENAME}}|Документация]] * [[{{#titleparts: {{TALKPAGENAME}} | -1 }}|Обсуждение]] * [[Служебная:Whatlinkshere/{{#titleparts: {{SUBJECTPAGENAME}} | -1 }}|Где используется]] {{#ifeq: {{NAMESPACE}} | {{ns:Template}} | ** {{Параметры шаблона|{{#titleparts: {{PAGENAME}} | -1 }}}} }}</div><!-- -->{{#if: {{{nocat|}}} || {{#ifexist: {{NAMESPACE}}:{{BASEPAGENAME}} || [[Категория:Шаблоны:Документация несуществующих шаблонов]] }} }} }}{{#if: {{{nocat|}}} || {{#ifeq: {{NAMESPACE}} | Модуль | [[Категория:Модули:Документация]] | [[Категория:Шаблоны:Документация]] }} }} }}</includeonly><noinclude>{{doc}}</noinclude> 9b09d5b771c19e45bd038d248dcf31e500e436ce Шаблон:Join 10 150 532 343 2024-08-16T15:58:47Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{<includeonly>safesubst:</includeonly>#invoke:Separated entries|main|separator={{{separator|}}}}}<noinclude> {{doc}} <!-- Категории — на подстраницу /doc, интервики — в Викиданные. --> </noinclude> 92bb17b5322d3ae0ceab93d4dad3d31810d47eb0 Шаблон:Namespace detect 10 233 534 533 2024-08-16T15:58:48Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{#switch: {{lc: <!--Lower case the result--> <!--If no or empty "demospace" parameter then detect namespace--> {{#if:{{{demospace|}}} | {{{demospace}}} | {{#ifeq:{{NAMESPACE}}|{{ns:0}} | main | {{#ifeq:{{NAMESPACE}}|{{TALKSPACE}} | {{#if:{{{talk|}}} | talk | {{#if:{{{andtalk|}}}|{{SUBJECTSPACE}}|talk}} }} | {{NAMESPACE}} }} }} }} }} <!-- Only one of the lines below will be executed --> <!-- Respecting empty parameters on purpose --> | main = {{{main| {{{other|}}} }}} | talk | обсуждение = {{{talk| {{{other|}}} }}} | user | участник = {{{user| {{{other|}}} }}} | wikipedia | википедия = {{{wikipedia| {{{other|}}} }}} | file | image | файл = {{{file| {{{image| {{{other|}}} }}} }}} | mediawiki | медиавики = {{{mediawiki| {{{other|}}} }}} | template | шаблон = {{{template| {{{other|}}} }}} | help | справка = {{{help| {{{other|}}} }}} | category | категория = {{{category| {{{other|}}} }}} | portal | портал = {{{portal| {{{other|}}} }}} | other | #default = {{{other|}}} <!--"demospace=other" or a new namespace--> }}<!--End switch--><noinclude> {{documentation}}{{Указание авторства русскоязычной Википедии}} </noinclude> 058c2deda5bf3cd3190672c4b14ab9f0c072ce03 Шаблон:Replace 10 145 536 333 2024-08-16T15:58:48Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{safesubst:<noinclude />#invoke:String|replace|source={{{1}}}|{{{2}}}|{{{3}}}|plain={{{plain|true}}}|count={{{count|}}}}}<noinclude> {{doc}} </noinclude> 7752c3c70ae8c46a89a0808aa282956866dbba5b Шаблон:Str left 10 146 538 335 2024-08-16T15:58:49Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{<includeonly>safesubst:</includeonly>padleft:|{{{2|1}}}|{{{1|}}}}}<noinclude> {{doc}} </noinclude> c1f57b63826f4d455dcaec8d2c24a2b8268f42ec Шаблон:Str len 10 166 540 375 2024-08-16T15:58:49Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{{{{|safesubst:}}}#invoke:String|len|s={{{1|}}}}}<noinclude> {{doc}} <!-- Add categories and interwikis to the /doc subpage, not here! --> </noinclude> 95f10258d5214440d2706952656564f216c2e4cc Шаблон:Str rightc 10 167 542 377 2024-08-16T15:58:49Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{<includeonly>safesubst:</includeonly>Str sub|{{{1}}}|{{<includeonly>safesubst:</includeonly>#expr:{{<includeonly>safesubst:</includeonly>Str len|{{{1}}}}}-{{{2}}}}}|{{{2}}}}}<noinclude>{{doc}}</noinclude> 0401d500dcc2224d44867ba0ea1f6c0fbeb758a0 Шаблон:Str sub 10 164 544 371 2024-08-16T15:58:49Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <includeonly>{{{{{|safesubst:}}}#invoke:String|sublength|s={{{1}}}|i={{{2|0}}}|len={{{3|0}}}}}</includeonly><noinclude> {{doc}} </noinclude> 3043790f8803e868cf6097b475fd58ba742887fe Шаблон:T 10 161 546 365 2024-08-16T15:58:50Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki #перенаправление [[Шаблон:Tl]] c0a76efe437d8a513d9f6878297f399a23944abd Шаблон:Tl 10 162 548 367 2024-08-16T15:58:50Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{{{{|safesubst:}}}#invoke: Template call code | withoutParams }}<noinclude>{{doc}}</noinclude> 61fe4d068895a5e7e5802767f5d7df71a7561c57 Шаблон:Tlinks 10 234 550 549 2024-08-16T15:58:50Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki #перенаправление [[Шаблон:Действия для страницы]] 8d69cbc167e009846a8f6ad7cd75b790882aeff5 Шаблон:Yesno 10 131 552 305 2024-08-16T15:58:51Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{<includeonly>safesubst:</includeonly>#switch: {{<includeonly>safesubst:</includeonly>lc: {{{1|¬}}} }} |no |n |нет |false |0 = {{{no|<!-- null -->}}} | = {{{blank|{{{no|<!-- null -->}}}}}} |¬ = {{{¬|}}} |yes |y |да |true |1 = {{{yes|yes}}} |#default = {{{def|{{{yes|yes}}}}}} }}<noinclude> {{Documentation}} </noinclude> 4e236854c477d07a225c2ab6c016c389b133e8d3 Шаблон:Yesno-yes 10 153 554 349 2024-08-16T15:58:51Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{safesubst:<noinclude />yesno|{{{1}}}|yes={{{yes|yes}}}|no={{{no|no}}}|blank={{{blank|yes}}}|¬={{{¬|yes}}}|def={{{def|yes}}}}}<noinclude> {{doc}} </noinclude> 3792ff694708f98102e3a6d556abe73bedc29069 Шаблон:Действия для страницы 10 174 556 391 2024-08-16T15:58:51Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <templatestyles src="Шаблон:Действия для страницы/styles.css" /><div style="{{#ifeq: {{yesno-yes|{{{right|}}}}} | yes || float:none; }}" class="ts-tlinks-tlinks mw-editsection-like plainlinks"><span class="mw-editsection-bracket">[</span><!-- -->{{join|separator=<span class="mw-editsection-divider"> &amp;#124; </span> |1={{#ifexist: {{#rel2abs: {{{lc|}}} }} | {{#ifeq: {{{dislooklink|{{{noview|}}}}}} | yes || [[{{{lc}}}|просмотр]] }} }} |2={{#ifexist: {{#rel2abs: {{{lc|}}} }} | [[Special:EditPage/{{#rel2abs: {{{lc}}} }}|править]] }} |3={{#ifexist: {{#rel2abs: {{{lc|}}} }} | {{#ifeq: {{{dishistlink|{{{nohistory|}}}}}} | yes || [[Special:PageHistory/{{#rel2abs: {{{lc}}} }}|история]] }} }} |4={{#ifexist: {{#rel2abs: {{{lc|}}} }} | | [{{fullurl:{{#rel2abs: {{{lc}}} }}|action=edit&redlink=1}} создать] }} |5={{#ifeq: {{{diswatchlink|{{{nowatch|}}}}}} | yes || [{{fullurl:{{#rel2abs: {{{lc}}} }}|action=watch}} следить] }} |6={{#ifeq: {{{disupdlink|{{{noupdate|}}}}}} | yes || {{очистить кэш|обновить|nocat=1}}</span> }} }}<span class="mw-editsection-bracket">]</span></div><noinclude> {{doc}} </noinclude> 9ee2c9eed92e2ecc9377a7b9486ad8bc214a83d4 Шаблон:Действия для страницы/styles.css 10 175 558 393 2024-08-16T15:58:51Z DuOfOrl 5 1 версия импортирована sanitized-css text/css .ts-tlinks-tlinks { font-weight: normal; float: right; line-height: inherit; } .ts-tlinks-tlinks .mw-editsection-divider { display: inline; } /* [[Категория:Шаблоны:Подстраницы CSS]] */ a003e896d263c29e66d2246b210e5d73e577ea46 Шаблон:Указание авторства русскоязычной Википедии 10 235 560 559 2024-08-16T15:58:52Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <includeonly>{| style="border: 1px solid #e0e0e0; background-color: #f8f8f8; color:black; margin: 5px auto; width: 60%;" |- | style="padding: 3px 10px;" | [[File:Wikipedia-logo-v2.svg|30px|Wikipedia logo]] | style="font-size: 90%; padding: 3px;" |{{Namespace detect|template=Данный шаблон|other=Данная страница}} использует материал из {{Namespace detect|template=шаблона|other=страницы}} [[w:ru:{{{1|{{FULLPAGENAME}}}}}|{{{1|{{FULLPAGENAME}}}}}]] с русскоязычной Википедии, который выпущен под [[w:ru:Википедия:Текст лицензии Creative Commons Attribution-ShareAlike 3.0 Unported|лицензией Creative Commons Attribution-ShareAlike 3.0 Unported]] ([https://ru.wikipedia.org/w/index.php?title={{urlencode:{{{1|{{FULLPAGENAME}}}}}}}&action=history посмотреть авторов]). |} [[Категория:{{Namespace detect|main=Статьи|category=Категории|file=Файлы|template=Шаблоны|other=Страницы}} из русскоязычной Википедии‎]]</includeonly> <noinclude> {{Doc}} [[Категория:Шаблоны с указанием авторства]] {{Указание авторства англоязычной Википедии|Template:En-WP attribution notice}} </noinclude> f6a3b5534c9f0bd71170f01c372f6d47cc03c302 Шаблон:Якорь 10 236 562 561 2024-08-16T15:58:53Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{#invoke:якорь|main}}<noinclude> {{doc}}{{Указание авторства русскоязычной Википедии}} <!-- Добавляйте категории на страницу документацию, не сюда --> </noinclude> d3f6a8195150483ee5b8b616a2aae7afbd3a3e0b Модуль:Arguments 828 124 564 291 2024-08-16T15:58:53Z DuOfOrl 5 1 версия импортирована Scribunto text/plain -- This module provides easy processing of arguments passed to Scribunto from -- #invoke. It is intended for use by other Lua modules, and should not be -- called from #invoke directly. local libraryUtil = require('libraryUtil') local checkType = libraryUtil.checkType local arguments = {} -- Generate four different tidyVal functions, so that we don't have to check the -- options every time we call it. local function tidyValDefault(key, val) if type(val) == 'string' then val = val:match('^%s*(.-)%s*$') if val == '' then return nil else return val end else return val end end local function tidyValTrimOnly(key, val) if type(val) == 'string' then return val:match('^%s*(.-)%s*$') else return val end end local function tidyValRemoveBlanksOnly(key, val) if type(val) == 'string' then if val:find('%S') then return val else return nil end else return val end end local function tidyValNoChange(key, val) return val end local function matchesTitle(given, title) local tp = type( given ) return (tp == 'string' or tp == 'number') and mw.title.new( given ).prefixedText == title end local translate_mt = { __index = function(t, k) return k end } function arguments.getArgs(frame, options) checkType('getArgs', 1, frame, 'table', true) checkType('getArgs', 2, options, 'table', true) frame = frame or {} options = options or {} --[[ -- Set up argument translation. --]] options.translate = options.translate or {} if getmetatable(options.translate) == nil then setmetatable(options.translate, translate_mt) end if options.backtranslate == nil then options.backtranslate = {} for k,v in pairs(options.translate) do options.backtranslate[v] = k end end if options.backtranslate and getmetatable(options.backtranslate) == nil then setmetatable(options.backtranslate, { __index = function(t, k) if options.translate[k] ~= k then return nil else return k end end }) end --[[ -- Get the argument tables. If we were passed a valid frame object, get the -- frame arguments (fargs) and the parent frame arguments (pargs), depending -- on the options set and on the parent frame's availability. If we weren't -- passed a valid frame object, we are being called from another Lua module -- or from the debug console, so assume that we were passed a table of args -- directly, and assign it to a new variable (luaArgs). --]] local fargs, pargs, luaArgs if type(frame.args) == 'table' and type(frame.getParent) == 'function' then if options.wrappers then --[[ -- The wrappers option makes Module:Arguments look up arguments in -- either the frame argument table or the parent argument table, but -- not both. This means that users can use either the #invoke syntax -- or a wrapper template without the loss of performance associated -- with looking arguments up in both the frame and the parent frame. -- Module:Arguments will look up arguments in the parent frame -- if it finds the parent frame's title in options.wrapper; -- otherwise it will look up arguments in the frame object passed -- to getArgs. --]] local parent = frame:getParent() if not parent then fargs = frame.args else local title = parent:getTitle():gsub('/песочница$', '') local found = false if matchesTitle(options.wrappers, title) then found = true elseif type(options.wrappers) == 'table' then for _,v in pairs(options.wrappers) do if matchesTitle(v, title) then found = true break end end end -- We test for false specifically here so that nil (the default) acts like true. if found or options.frameOnly == false then pargs = parent.args end if not found or options.parentOnly == false then fargs = frame.args end end else -- options.wrapper isn't set, so check the other options. if not options.parentOnly then fargs = frame.args end if not options.frameOnly then local parent = frame:getParent() pargs = parent and parent.args or nil end end if options.parentFirst then fargs, pargs = pargs, fargs end else luaArgs = frame end -- Set the order of precedence of the argument tables. If the variables are -- nil, nothing will be added to the table, which is how we avoid clashes -- between the frame/parent args and the Lua args. local argTables = {fargs} argTables[#argTables + 1] = pargs argTables[#argTables + 1] = luaArgs --[[ -- Generate the tidyVal function. If it has been specified by the user, we -- use that; if not, we choose one of four functions depending on the -- options chosen. This is so that we don't have to call the options table -- every time the function is called. --]] local tidyVal = options.valueFunc if tidyVal then if type(tidyVal) ~= 'function' then error( "bad value assigned to option 'valueFunc'" .. '(function expected, got ' .. type(tidyVal) .. ')', 2 ) end elseif options.trim ~= false then if options.removeBlanks ~= false then tidyVal = tidyValDefault else tidyVal = tidyValTrimOnly end else if options.removeBlanks ~= false then tidyVal = tidyValRemoveBlanksOnly else tidyVal = tidyValNoChange end end --[[ -- Set up the args, metaArgs and nilArgs tables. args will be the one -- accessed from functions, and metaArgs will hold the actual arguments. Nil -- arguments are memoized in nilArgs, and the metatable connects all of them -- together. --]] local args, metaArgs, nilArgs, metatable = {}, {}, {}, {} setmetatable(args, metatable) local function mergeArgs(tables) --[[ -- Accepts multiple tables as input and merges their keys and values -- into one table. If a value is already present it is not overwritten; -- tables listed earlier have precedence. We are also memoizing nil -- values, which can be overwritten if they are 's' (soft). --]] for _, t in ipairs(tables) do for key, val in pairs(t) do if metaArgs[key] == nil and nilArgs[key] ~= 'h' then local tidiedVal = tidyVal(key, val) if tidiedVal == nil then nilArgs[key] = 's' else metaArgs[key] = tidiedVal end end end end end --[[ -- Define metatable behaviour. Arguments are memoized in the metaArgs table, -- and are only fetched from the argument tables once. Fetching arguments -- from the argument tables is the most resource-intensive step in this -- module, so we try and avoid it where possible. For this reason, nil -- arguments are also memoized, in the nilArgs table. Also, we keep a record -- in the metatable of when pairs and ipairs have been called, so we do not -- run pairs and ipairs on the argument tables more than once. We also do -- not run ipairs on fargs and pargs if pairs has already been run, as all -- the arguments will already have been copied over. --]] metatable.__index = function (t, key) --[[ -- Fetches an argument when the args table is indexed. First we check -- to see if the value is memoized, and if not we try and fetch it from -- the argument tables. When we check memoization, we need to check -- metaArgs before nilArgs, as both can be non-nil at the same time. -- If the argument is not present in metaArgs, we also check whether -- pairs has been run yet. If pairs has already been run, we return nil. -- This is because all the arguments will have already been copied into -- metaArgs by the mergeArgs function, meaning that any other arguments -- must be nil. --]] if type(key) == 'string' then key = options.translate[key] end local val = metaArgs[key] if val ~= nil then return val elseif metatable.donePairs or nilArgs[key] then return nil end for _, argTable in ipairs(argTables) do local argTableVal = tidyVal(key, argTable[key]) if argTableVal ~= nil then metaArgs[key] = argTableVal return argTableVal end end nilArgs[key] = 'h' return nil end metatable.__newindex = function (t, key, val) -- This function is called when a module tries to add a new value to the -- args table, or tries to change an existing value. if type(key) == 'string' then key = options.translate[key] end if options.readOnly then error( 'could not write to argument table key "' .. tostring(key) .. '"; the table is read-only', 2 ) elseif options.noOverwrite and args[key] ~= nil then error( 'could not write to argument table key "' .. tostring(key) .. '"; overwriting existing arguments is not permitted', 2 ) elseif val == nil then --[[ -- If the argument is to be overwritten with nil, we need to erase -- the value in metaArgs, so that __index, __pairs and __ipairs do -- not use a previous existing value, if present; and we also need -- to memoize the nil in nilArgs, so that the value isn't looked -- up in the argument tables if it is accessed again. --]] metaArgs[key] = nil nilArgs[key] = 'h' else metaArgs[key] = val end end local function translatenext(invariant) local k, v = next(invariant.t, invariant.k) invariant.k = k if k == nil then return nil elseif type(k) ~= 'string' or not options.backtranslate then return k, v else local backtranslate = options.backtranslate[k] if backtranslate == nil then -- Skip this one. This is a tail call, so this won't cause stack overflow return translatenext(invariant) else return backtranslate, v end end end metatable.__pairs = function () -- Called when pairs is run on the args table. if not metatable.donePairs then mergeArgs(argTables) metatable.donePairs = true end return translatenext, { t = metaArgs } end local function inext(t, i) -- This uses our __index metamethod local v = t[i + 1] if v ~= nil then return i + 1, v end end metatable.__ipairs = function (t) -- Called when ipairs is run on the args table. return inext, t, 0 end return args end return arguments e6be8dfccffa2057c3d50700f350d8d140c1dbf9 Модуль:Separated entries 828 158 566 359 2024-08-16T15:58:53Z DuOfOrl 5 1 версия импортирована Scribunto text/plain -- This module takes positional parameters as input and concatenates them with -- an optional separator. The final separator (the "conjunction") can be -- specified independently, enabling natural-language lists like -- "foo, bar, baz and qux". local compressSparseArray = require('Module:TableTools').compressSparseArray local p = {} function p._main(args) local separator = args.separator -- Decode (convert to Unicode) HTML escape sequences, such as "&#32;" for space. and mw.text.decode(args.separator) or '' local conjunction = args.conjunction and mw.text.decode(args.conjunction) or separator -- Discard named parameters. local values = compressSparseArray(args) return mw.text.listToText(values, separator, conjunction) end local function makeInvokeFunction(separator, conjunction) return function (frame) local args = require('Module:Arguments').getArgs(frame) args.separator = separator or args.separator args.conjunction = conjunction or args.conjunction return p._main(args) end end p.main = makeInvokeFunction() p.br = makeInvokeFunction('<br />') p.newline = makeInvokeFunction('\n') p.comma = makeInvokeFunction(mw.message.new('comma-separator'):plain()) return p 33a68f0a46d62c42b6523a548f0f881e82ecfe58 Модуль:String 828 138 568 319 2024-08-16T15:58:54Z DuOfOrl 5 1 версия импортирована Scribunto text/plain --[[ This module is intended to provide access to basic string functions. Most of the functions provided here can be invoked with named parameters, unnamed parameters, or a mixture. If named parameters are used, Mediawiki will automatically remove any leading or trailing whitespace from the parameter. Depending on the intended use, it may be advantageous to either preserve or remove such whitespace. Global options ignore_errors: If set to 'true' or 1, any error condition will result in an empty string being returned rather than an error message. error_category: If an error occurs, specifies the name of a category to include with the error message. The default category is [Category:Errors reported by Module String]. no_category: If set to 'true' or 1, no category will be added if an error is generated. Unit tests for this module are available at Module:String/tests. ]] local str = {} --[[ subcount This function returns the count of substring in source string. Usage: {{#invoke:String|subcount|source_string|substring|plain_flag}} OR {{#invoke:String|subcount|s=source_string|pattern=substring|plain=plain_flag}} Parameters s: The string to search pattern: The pattern or string to find within the string plain: A flag indicating that the substring should be understood as plain text. Defaults to true. If invoked using named parameters, Mediawiki will automatically remove any leading or trailing whitespace from the target string. ]] function str.subcount( frame ) local new_args = str._getParameters( frame.args, {'s', 'pattern', 'plain'} ); local s = new_args['s'] or ''; local plain_flag = str._getBoolean( new_args['plain'] or true ); local pattern = new_args['pattern'] or ''; if s == '' or pattern == '' then return 0; end if plain_flag then pattern = str._escapePattern( pattern ); end local _, count = mw.ustring.gsub(s, pattern, "") return count; end --[[ len This function returns the length of the target string. Usage: {{#invoke:String|len|target_string|}} OR {{#invoke:String|len|s=target_string}} Parameters s: The string whose length to report If invoked using named parameters, Mediawiki will automatically remove any leading or trailing whitespace from the target string. ]] function str.len( frame ) local new_args = str._getParameters( frame.args, {'s'} ); local s = new_args['s'] or ''; return mw.ustring.len( s ) end --[[ sub This function returns a substring of the target string at specified indices. Usage: {{#invoke:String|sub|target_string|start_index|end_index}} OR {{#invoke:String|sub|s=target_string|i=start_index|j=end_index}} Parameters s: The string to return a subset of i: The fist index of the substring to return, defaults to 1. j: The last index of the string to return, defaults to the last character. The first character of the string is assigned an index of 1. If either i or j is a negative value, it is interpreted the same as selecting a character by counting from the end of the string. Hence, a value of -1 is the same as selecting the last character of the string. If the requested indices are out of range for the given string, an error is reported. ]] function str.sub( frame ) local new_args = str._getParameters( frame.args, { 's', 'i', 'j' } ); local s = new_args['s'] or ''; local i = tonumber( new_args['i'] ) or 1; local j = tonumber( new_args['j'] ) or -1; local len = mw.ustring.len( s ); -- Convert negatives for range checking if i < 0 then i = len + i + 1; end if j < 0 then j = len + j + 1; end if i > len or j > len or i < 1 or j < 1 then return str._error( 'Значение индекса подстроки выходит за допустимые границы' ); end if j < i then return str._error( 'Неверный порядок индексов подстроки' ); end return mw.ustring.sub( s, i, j ) end --[[ This function implements that features of {{str sub old}} and is kept in order to maintain these older templates. ]] function str.sublength( frame ) local i = tonumber( frame.args.i ) or 0 local len = tonumber( frame.args.len ) return mw.ustring.sub( frame.args.s, i + 1, len and ( i + len ) ) end --[[ match This function returns a substring from the source string that matches a specified pattern. Usage: {{#invoke:String|match|source_string|pattern_string|start_index|match_number|plain_flag|nomatch_output}} OR {{#invoke:String|pos|s=source_string|pattern=pattern_string|start=start_index |match=match_number|plain=plain_flag|nomatch=nomatch_output}} Parameters s: The string to search pattern: The pattern or string to find within the string start: The index within the source string to start the search. The first character of the string has index 1. Defaults to 1. match: In some cases it may be possible to make multiple matches on a single string. This specifies which match to return, where the first match is match= 1. If a negative number is specified then a match is returned counting from the last match. Hence match = -1 is the same as requesting the last match. Defaults to 1. plain: A flag indicating that the pattern should be understood as plain text. Defaults to false. nomatch: If no match is found, output the "nomatch" value rather than an error. If invoked using named parameters, Mediawiki will automatically remove any leading or trailing whitespace from each string. In some circumstances this is desirable, in other cases one may want to preserve the whitespace. If the match_number or start_index are out of range for the string being queried, then this function generates an error. An error is also generated if no match is found. If one adds the parameter ignore_errors=true, then the error will be suppressed and an empty string will be returned on any failure. For information on constructing Lua patterns, a form of [regular expression], see: * http://www.lua.org/manual/5.1/manual.html#5.4.1 * http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Patterns * http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Ustring_patterns ]] function str.match( frame ) local new_args = str._getParameters( frame.args, {'s', 'pattern', 'start', 'match', 'plain', 'nomatch'} ); local s = new_args['s'] or ''; local start = tonumber( new_args['start'] ) or 1; local plain_flag = str._getBoolean( new_args['plain'] or false ); local pattern = new_args['pattern'] or ''; local match_index = math.floor( tonumber(new_args['match']) or 1 ); local nomatch = new_args['nomatch']; if s == '' then return str._error( 'Пустая строка поиска' ); end if pattern == '' then return str._error( 'Пустой шаблон поиска' ); end if math.abs(start) < 1 or math.abs(start) > mw.ustring.len( s ) then return str._error( 'Индекс начала поиска выходит за допустимые границы' ); end if match_index == 0 then return str._error( 'Индекс совпадения выходит за допустимые границы' ); end if plain_flag then pattern = str._escapePattern( pattern ); end local result if match_index == 1 then -- Find first match is simple case result = mw.ustring.match( s, pattern, start ) else if start > 1 then s = mw.ustring.sub( s, start ); end local iterator = mw.ustring.gmatch(s, pattern); if match_index > 0 then -- Forward search for w in iterator do match_index = match_index - 1; if match_index == 0 then result = w; break; end end else -- Reverse search local result_table = {}; local count = 1; for w in iterator do result_table[count] = w; count = count + 1; end result = result_table[ count + match_index ]; end end if result == nil then if nomatch == nil then return str._error( 'Совпадение не найдено' ); else return nomatch; end else return result; end end --[[ pos This function returns a single character from the target string at position pos. Usage: {{#invoke:String|pos|target_string|index_value}} OR {{#invoke:String|pos|target=target_string|pos=index_value}} Parameters target: The string to search pos: The index for the character to return If invoked using named parameters, Mediawiki will automatically remove any leading or trailing whitespace from the target string. In some circumstances this is desirable, in other cases one may want to preserve the whitespace. The first character has an index value of 1. If one requests a negative value, this function will select a character by counting backwards from the end of the string. In other words pos = -1 is the same as asking for the last character. A requested value of zero, or a value greater than the length of the string returns an error. ]] function str.pos( frame ) local new_args = str._getParameters( frame.args, {'target', 'pos'} ); local target_str = new_args['target'] or ''; local pos = tonumber( new_args['pos'] ) or 0; if pos == 0 or math.abs(pos) > mw.ustring.len( target_str ) then return str._error( 'Значение индекса строки выходит за допустимые границы' ); end return mw.ustring.sub( target_str, pos, pos ); end --[[ str_find This function duplicates the behavior of {{str_find}}, including all of its quirks. This is provided in order to support existing templates, but is NOT RECOMMENDED for new code and templates. New code is recommended to use the "find" function instead. Returns the first index in "source" that is a match to "target". Indexing is 1-based, and the function returns -1 if the "target" string is not present in "source". Important Note: If the "target" string is empty / missing, this function returns a value of "1", which is generally unexpected behavior, and must be accounted for separatetly. ]] function str.str_find( frame ) local new_args = str._getParameters( frame.args, {'source', 'target'} ); local source_str = new_args['source'] or ''; local target_str = new_args['target'] or ''; if target_str == '' then return 1; end local start = mw.ustring.find( source_str, target_str, 1, true ) if start == nil then start = -1 end return start end --[[ find This function allows one to search for a target string or pattern within another string. Usage: {{#invoke:String|find|source_str|target_string|start_index|plain_flag}} OR {{#invoke:String|find|source=source_str|target=target_str|start=start_index|plain=plain_flag}} Parameters source: The string to search target: The string or pattern to find within source start: The index within the source string to start the search, defaults to 1 plain: Boolean flag indicating that target should be understood as plain text and not as a Lua style regular expression, defaults to true If invoked using named parameters, Mediawiki will automatically remove any leading or trailing whitespace from the parameter. In some circumstances this is desirable, in other cases one may want to preserve the whitespace. This function returns the first index >= "start" where "target" can be found within "source". Indices are 1-based. If "target" is not found, then this function returns 0. If either "source" or "target" are missing / empty, this function also returns 0. This function should be safe for UTF-8 strings. ]] function str.find( frame ) local new_args = str._getParameters( frame.args, {'source', 'target', 'start', 'plain' } ); local source_str = new_args['source'] or ''; local pattern = new_args['target'] or ''; local start_pos = tonumber(new_args['start']) or 1; local plain = new_args['plain'] or true; if source_str == '' or pattern == '' then return 0; end plain = str._getBoolean( plain ); local start = mw.ustring.find( source_str, pattern, start_pos, plain ) if start == nil then start = 0 end return start end --[[ replace This function allows one to replace a target string or pattern within another string. Usage: {{#invoke:String|replace|source_str|pattern_string|replace_string|replacement_count|plain_flag}} OR {{#invoke:String|replace|source=source_string|pattern=pattern_string|replace=replace_string| count=replacement_count|plain=plain_flag}} Parameters source: The string to search pattern: The string or pattern to find within source replace: The replacement text count: The number of occurences to replace, defaults to all. plain: Boolean flag indicating that pattern should be understood as plain text and not as a Lua style regular expression, defaults to true ]] function str.replace( frame ) local new_args = str._getParameters( frame.args, {'source', 'pattern', 'replace', 'count', 'plain' } ); local source_str = new_args['source'] or ''; local pattern = new_args['pattern'] or ''; local replace = new_args['replace'] or ''; local count = tonumber( new_args['count'] ); local plain = new_args['plain'] or true; if source_str == '' or pattern == '' then return source_str; end plain = str._getBoolean( plain ); if plain then pattern = str._escapePattern( pattern ); replace = mw.ustring.gsub( replace, "%%", "%%%%" ); --Only need to escape replacement sequences. end local result; if count ~= nil then result = mw.ustring.gsub( source_str, pattern, replace, count ); else result = mw.ustring.gsub( source_str, pattern, replace ); end return result; end --[[ This function adds support for escaping parts of the patterns when using [plain=false]. ]] function str.escape( frame ) local new_args = str._getParameters( frame.args, {'pattern' } ); local pattern = new_args['pattern'] or ''; local result = ''; result = str._escapePattern( pattern ); return result; end --[[ Internal compare string function ]] function str._strcmp(a , b) local s1c = mw.ustring.gcodepoint( a ); local s2c = mw.ustring.gcodepoint( b ); while true do local c1 = s1c(); local c2 = s2c(); if c1 == nil then if c2 == nil then return 0 else return -1 end else if c2 ~= nil then if c1 ~= c2 then return c1 < c2 and -1 or 1 end else return 1 end end end return 0 end --[[ compare This function compare two UTF-8 strings Usage: {{#invoke:String|compare|str1|str2}} Returns: 0 - if strings are equal 1 - if st1 > str2 -1 - if str1 < str2 ]] function str.compare(frame) local str1 = frame.args[1] or ''; local str2 = frame.args[2] or ''; return str._strcmp(str1 , str2) end --[[ simple function to pipe string.rep to templates. ]] function str.rep( frame ) local repetitions = tonumber( frame.args[2] ) if not repetitions then return str._error( 'функция rep ожидает число во втором параметре, а получено "' .. ( frame.args[2] or '' ) .. '"' ) end return string.rep( frame.args[1] or '', repetitions ) end --[[ Helper function that populates the argument list given that user may need to use a mix of named and unnamed parameters. This is relevant because named parameters are not identical to unnamed parameters due to string trimming, and when dealing with strings we sometimes want to either preserve or remove that whitespace depending on the application. ]] function str._getParameters( frame_args, arg_list ) local new_args = {}; local index = 1; local value; for i,arg in ipairs( arg_list ) do value = frame_args[arg] if value == nil then value = frame_args[index]; index = index + 1; end new_args[arg] = value; end return new_args; end --[[ Helper function to handle error messages. ]] function str._error( error_str ) local frame = mw.getCurrentFrame(); local error_category = frame.args.error_category or 'Страницы с ошибками модуля String'; local ignore_errors = frame.args.ignore_errors or false; local no_category = frame.args.no_category or false; if str._getBoolean(ignore_errors) then return ''; end local error_str = '<strong class="error">Ошибка модуля String: ' .. error_str .. '</strong>'; if error_category ~= '' and not str._getBoolean( no_category ) then error_str = '[[Категория:' .. error_category .. ']]' .. error_str; end return error_str; end --[[ Helper Function to interpret boolean strings ]] function str._getBoolean( boolean_str ) local boolean_value; if type( boolean_str ) == 'string' then boolean_str = boolean_str:lower(); if boolean_str == 'false' or boolean_str == 'no' or boolean_str == '0' or boolean_str == '' then boolean_value = false; else boolean_value = true; end elseif type( boolean_str ) == 'boolean' then boolean_value = boolean_str; else error( 'Логическое значение не найдено' ); end return boolean_value end --[[ Helper function that escapes all pattern characters so that they will be treated as plain text. ]] function str._escapePattern( pattern_str ) return mw.ustring.gsub( pattern_str, "([%(%)%.%%%+%-%*%?%[%^%$%]])", "%%%1" ); end return str b4a4e099d7fab23576bae7af327a44c87d13f9cb Модуль:TableTools 828 125 570 293 2024-08-16T15:58:54Z DuOfOrl 5 1 версия импортирована Scribunto text/plain --[[ ------------------------------------------------------------------------------------ -- TableTools -- -- -- -- This module includes a number of functions for dealing with Lua tables. -- -- It is a meta-module, meant to be called from other Lua modules, and should -- -- not be called directly from #invoke. -- ------------------------------------------------------------------------------------ --]] local libraryUtil = require('libraryUtil') local p = {} -- Define often-used variables and functions. local floor = math.floor local infinity = math.huge local checkType = libraryUtil.checkType local checkTypeMulti = libraryUtil.checkTypeMulti --[[ ------------------------------------------------------------------------------------ -- isPositiveInteger -- -- This function returns true if the given value is a positive integer, and false -- if not. Although it doesn't operate on tables, it is included here as it is -- useful for determining whether a given table key is in the array part or the -- hash part of a table. ------------------------------------------------------------------------------------ --]] function p.isPositiveInteger(v) if type(v) == 'number' and v >= 1 and floor(v) == v and v < infinity then return true else return false end end --[[ ------------------------------------------------------------------------------------ -- isNan -- -- This function returns true if the given number is a NaN value, and false -- if not. Although it doesn't operate on tables, it is included here as it is -- useful for determining whether a value can be a valid table key. Lua will -- generate an error if a NaN is used as a table key. ------------------------------------------------------------------------------------ --]] function p.isNan(v) if type(v) == 'number' and tostring(v) == '-nan' then return true else return false end end --[[ ------------------------------------------------------------------------------------ -- shallowClone -- -- This returns a clone of a table. The value returned is a new table, but all -- subtables and functions are shared. Metamethods are respected, but the returned -- table will have no metatable of its own. ------------------------------------------------------------------------------------ --]] function p.shallowClone(t) local ret = {} for k, v in pairs(t) do ret[k] = v end return ret end --[[ ------------------------------------------------------------------------------------ -- removeDuplicates -- -- This removes duplicate values from an array. Non-positive-integer keys are -- ignored. The earliest value is kept, and all subsequent duplicate values are -- removed, but otherwise the array order is unchanged. ------------------------------------------------------------------------------------ --]] function p.removeDuplicates(t) checkType('removeDuplicates', 1, t, 'table') local isNan = p.isNan local ret, exists = {}, {} for i, v in ipairs(t) do if isNan(v) then -- NaNs can't be table keys, and they are also unique, so we don't need to check existence. ret[#ret + 1] = v else if not exists[v] then ret[#ret + 1] = v exists[v] = true end end end return ret end --[[ ------------------------------------------------------------------------------------ -- numKeys -- -- This takes a table and returns an array containing the numbers of any numerical -- keys that have non-nil values, sorted in numerical order. ------------------------------------------------------------------------------------ --]] function p.numKeys(t) checkType('numKeys', 1, t, 'table') local isPositiveInteger = p.isPositiveInteger local nums = {} for k, v in pairs(t) do if isPositiveInteger(k) then nums[#nums + 1] = k end end table.sort(nums) return nums end --[[ ------------------------------------------------------------------------------------ -- affixNums -- -- This takes a table and returns an array containing the numbers of keys with the -- specified prefix and suffix. For example, for the table -- {a1 = 'foo', a3 = 'bar', a6 = 'baz'} and the prefix "a", affixNums will -- return {1, 3, 6}. ------------------------------------------------------------------------------------ --]] function p.affixNums(t, prefix, suffix) checkType('affixNums', 1, t, 'table') checkType('affixNums', 2, prefix, 'string', true) checkType('affixNums', 3, suffix, 'string', true) local function cleanPattern(s) -- Cleans a pattern so that the magic characters ()%.[]*+-?^$ are interpreted literally. s = s:gsub('([%(%)%%%.%[%]%*%+%-%?%^%$])', '%%%1') return s end prefix = prefix or '' suffix = suffix or '' prefix = cleanPattern(prefix) suffix = cleanPattern(suffix) local pattern = '^' .. prefix .. '([1-9]%d*)' .. suffix .. '$' local nums = {} for k, v in pairs(t) do if type(k) == 'string' then local num = mw.ustring.match(k, pattern) if num then nums[#nums + 1] = tonumber(num) end end end table.sort(nums) return nums end --[[ ------------------------------------------------------------------------------------ -- numData -- -- Given a table with keys like ("foo1", "bar1", "foo2", "baz2"), returns a table -- of subtables in the format -- { [1] = {foo = 'text', bar = 'text'}, [2] = {foo = 'text', baz = 'text'} } -- Keys that don't end with an integer are stored in a subtable named "other". -- The compress option compresses the table so that it can be iterated over with -- ipairs. ------------------------------------------------------------------------------------ --]] function p.numData(t, compress) checkType('numData', 1, t, 'table') checkType('numData', 2, compress, 'boolean', true) local ret = {} for k, v in pairs(t) do local prefix, num = mw.ustring.match(tostring(k), '^([^0-9]*)([1-9][0-9]*)$') if num then num = tonumber(num) local subtable = ret[num] or {} if prefix == '' then -- Positional parameters match the blank string; put them at the start of the subtable instead. prefix = 1 end subtable[prefix] = v ret[num] = subtable else local subtable = ret.other or {} subtable[k] = v ret.other = subtable end end if compress then local other = ret.other ret = p.compressSparseArray(ret) ret.other = other end return ret end --[[ ------------------------------------------------------------------------------------ -- compressSparseArray -- -- This takes an array with one or more nil values, and removes the nil values -- while preserving the order, so that the array can be safely traversed with -- ipairs. ------------------------------------------------------------------------------------ --]] function p.compressSparseArray(t) checkType('compressSparseArray', 1, t, 'table') local ret = {} local nums = p.numKeys(t) for _, num in ipairs(nums) do ret[#ret + 1] = t[num] end return ret end --[[ ------------------------------------------------------------------------------------ -- sparseIpairs -- -- This is an iterator for sparse arrays. It can be used like ipairs, but can -- handle nil values. ------------------------------------------------------------------------------------ --]] function p.sparseIpairs(t) checkType('sparseIpairs', 1, t, 'table') local nums = p.numKeys(t) local i = 0 local lim = #nums return function () i = i + 1 if i <= lim then local key = nums[i] return key, t[key] else return nil, nil end end end --[[ ------------------------------------------------------------------------------------ -- size -- -- This returns the size of a key/value pair table. It will also work on arrays, -- but for arrays it is more efficient to use the # operator. ------------------------------------------------------------------------------------ --]] function p.size(t) checkType('size', 1, t, 'table') local i = 0 for k in pairs(t) do i = i + 1 end return i end local function defaultKeySort(item1, item2) -- "number" < "string", so numbers will be sorted before strings. local type1, type2 = type(item1), type(item2) if type1 ~= type2 then return type1 < type2 else -- This will fail with table, boolean, function. return item1 < item2 end end --[[ Returns a list of the keys in a table, sorted using either a default comparison function or a custom keySort function. ]] function p.keysToList(t, keySort, checked) if not checked then checkType('keysToList', 1, t, 'table') checkTypeMulti('keysToList', 2, keySort, { 'function', 'boolean', 'nil' }) end local list = {} local index = 1 for key, value in pairs(t) do list[index] = key index = index + 1 end if keySort ~= false then keySort = type(keySort) == 'function' and keySort or defaultKeySort table.sort(list, keySort) end return list end --[[ Iterates through a table, with the keys sorted using the keysToList function. If there are only numerical keys, sparseIpairs is probably more efficient. ]] function p.sortedPairs(t, keySort) checkType('sortedPairs', 1, t, 'table') checkType('sortedPairs', 2, keySort, 'function', true) local list = p.keysToList(t, keySort, true) local i = 0 return function() i = i + 1 local key = list[i] if key ~= nil then return key, t[key] else return nil, nil end end end --[[ Returns true if all keys in the table are consecutive integers starting at 1. --]] function p.isArray(t) checkType("isArray", 1, t, "table") local i = 0 for k, v in pairs(t) do i = i + 1 if t[i] == nil then return false end end return true end -- { "a", "b", "c" } -> { a = 1, b = 2, c = 3 } function p.invert(array) checkType("invert", 1, array, "table") local map = {} for i, v in ipairs(array) do map[v] = i end return map end --[[ { "a", "b", "c" } -> { ["a"] = true, ["b"] = true, ["c"] = true } --]] function p.listToSet(t) checkType("listToSet", 1, t, "table") local set = {} for _, item in ipairs(t) do set[item] = true end return set end --[[ Recursive deep copy function. Preserves identities of subtables. ]] local function _deepCopy(orig, includeMetatable, already_seen) -- Stores copies of tables indexed by the original table. already_seen = already_seen or {} local copy = already_seen[orig] if copy ~= nil then return copy end if type(orig) == 'table' then copy = {} for orig_key, orig_value in pairs(orig) do copy[deepcopy(orig_key, includeMetatable, already_seen)] = deepcopy(orig_value, includeMetatable, already_seen) end already_seen[orig] = copy if includeMetatable then local mt = getmetatable(orig) if mt ~= nil then local mt_copy = deepcopy(mt, includeMetatable, already_seen) setmetatable(copy, mt_copy) already_seen[mt] = mt_copy end end else -- number, string, boolean, etc copy = orig end return copy end function p.deepCopy(orig, noMetatable, already_seen) checkType("deepCopy", 3, already_seen, "table", true) return _deepCopy(orig, not noMetatable, already_seen) end --[[ Concatenates all values in the table that are indexed by a number, in order. sparseConcat{ a, nil, c, d } => "acd" sparseConcat{ nil, b, c, d } => "bcd" ]] function p.sparseConcat(t, sep, i, j) local list = {} local list_i = 0 for _, v in p.sparseIpairs(t) do list_i = list_i + 1 list[list_i] = v end return table.concat(list, sep, i, j) end --[[ -- This returns the length of a table, or the first integer key n counting from -- 1 such that t[n + 1] is nil. It is similar to the operator #, but may return -- a different value when there are gaps in the array portion of the table. -- Intended to be used on data loaded with mw.loadData. For other tables, use #. -- Note: #frame.args in frame object always be set to 0, regardless of -- the number of unnamed template parameters, so use this function for -- frame.args. --]] function p.length(t) local i = 1 while t[i] ~= nil do i = i + 1 end return i - 1 end function p.inArray(arr, valueToFind) checkType("inArray", 1, arr, "table") -- if valueToFind is nil, error? for _, v in ipairs(arr) do if v == valueToFind then return true end end return false end return p fe918509f168332267834b3a6f5c219a9de5b2e7 Модуль:Template call code 828 126 572 295 2024-08-16T15:58:55Z DuOfOrl 5 1 версия импортирована Scribunto text/plain local getArgs = require('Module:Arguments').getArgs local ru = mw.language.new('ru') local p = {} -- Используется для того, чтобы можно было удалять элементы из таблицы local function copy(other) local res = {} for k, v in pairs(other) do res[k] = v end return res end local function makeInvokeFunc(funcName, flags) return function (frame) local args = copy(getArgs(frame, { trim = false, removeBlanks = false })) return p[funcName](args, flags) end end --предотвращает обработку вики-текста в отображении образца local function processText(str, nowiki) local res = str if nowiki then str = mw.text.unstripNoWiki(str) str = string.gsub(str, '%[', '&#91;') str = string.gsub(str, '%]', '&#93;') str = string.gsub(str, '<', '&lt;') str = string.gsub(str, '>', '&gt;') str = string.gsub(str, '{', '&#123;') str = string.gsub(str, '|', '&#124;') str = string.gsub(str, '}', '&#125;') str = string.gsub(str, '\'', '&#39;') str = string.gsub(str, '"', '&quot;') str = string.gsub(str, '(://)', '<span>%1</span>') end return str end local function addParams(args, params) local text, equals_pos, param, value = '', 0, '', '' local function addPipe() if params.spaced then text = text .. ' ' end text = text .. '<span class="' if not params.spaced then text = text .. ' ts-templateCallCode-pipe' end if not params.black then text = text .. ' ts-templateCallCode-weak' end -- &#124;, чтобы не трактовалось как разделитель ячеек в таблицах text = text .. '">&#124;</span>' end local beforeParam = '<span class="ts-templateCallCode-param">' local afterParam = '</span>' for k, v in pairs(args) do if type(k) == 'number' then -- Неименованные параметры if k >= params.from then equals_pos = v:find('=') if equals_pos and v:find('{{=}}') == equals_pos - 2 then equals_pos = nil end if equals_pos then -- Содержащие «=» преобразуем в именованные param = v:sub(1, equals_pos - 1) value = v:sub(equals_pos + 1) addPipe() text = text .. beforeParam .. processText(param, params.nowiki) .. '=' .. processText(value, params.nowiki) .. afterParam else -- Истинно неименованные addPipe() local paramValue = processText(v, params.nowiki) if #paramValue ~= 0 then text = text .. beforeParam .. paramValue .. afterParam end end end elseif not k:find('^_') then -- Именованные параметры, исключая модификаторы внешнего вида addPipe() text = text .. beforeParam .. processText(k, params.nowiki) .. '=' .. processText(v, params.nowiki) .. afterParam end end return text end function p._main(args, flags) local name = args[1] table.remove(args, 1) -- Вещи типа «=» в первом параметре if not name then for k, v in pairs(args) do if not k:find('^_') then name = k .. '=' .. v args[k] = nil break end end end local optpText if not flags.withoutParams then if name then local spanOffset = mw.ustring.find(name, '<span') -- След использования шаблона optp if spanOffset then optpText = mw.ustring.sub(name, spanOffset) name = mw.ustring.sub(name, 1, spanOffset - 1) end end end local yesno = require('Module:Yesno') local nolink, subst, podst, global, nav, noRedirect, ucFirst, black, nobr local tag, style, comment, lang, sister, global, textInPlaceOfName, namePrefix, prefix, postfix, nowiki local spaced, from if flags.withoutParams then for i, v in ipairs(args) do if v == 'nl' or v == 'nolink' then noLink = true elseif v == 's' then subst = true elseif v == 'п' then podst = true elseif v == 'g' then global = true elseif v == 'nav' then nav = true elseif v == 'noredir' then noRedirect = true elseif v == 'u' then ucFirst = true elseif v == 'b' then black = true elseif v == 'nobr' then nobr = true end end tag = args.tag or 'span' style = args.style comment = args.comment lang = args.lang sister = args.sister textInPlaceOfName = args.text namePrefix = args.nameprefix prefix = args.prefix postfix = args.postfix nowiki = args.nowiki else noLink = yesno(args._nolink or args._nl, false) or not yesno(args._link, false) subst = yesno(args._s, false) podst = yesno(args['_п'], false) global = yesno(args._g, false) nav = yesno(args._nav, false) noRedirect = yesno(args._noredir, false) ucFirst = yesno(args._u, false) black = yesno(args._b, false) nobr = yesno(args._nobr, false) tag = args._tag or 'span' style = args._style comment = args._comment lang = args._lang sister = args._sister textInPlaceOfName = args._text namePrefix = args._nameprefix prefix = args._prefix postfix = args._postfix nowiki = args._nowiki spaced = yesno(args._spaced, false) from = (tonumber(args._from) or 2) - 1 end global = global or name and mw.ustring.sub(name, 1, 1) == ':' black = black or tag ~= 'span' if textInPlaceOfName == '' then textInPlaceOfName = nil end if comment == '' then comment = nil end if lang == '' then lang = nil end if sister == '' then sister = nil end if namePrefix == '' then namePrefix = nil end if name then local trimmedName = mw.text.trim(name) if ru:lc(mw.ustring.sub(trimmedName, 1, 6)) == 'subst:' then subst = true name = mw.ustring.sub(trimmedName, 7) end if ru:lc(mw.ustring.sub(trimmedName, 1, 6)) == 'подст:' then podst = true name = mw.ustring.sub(trimmedName, 7) end end if subst then namePrefix = 'subst:' elseif podst then namePrefix = 'подст:' end local currentTitle = mw.title.getCurrentTitle() -- При опущенном первом параметре берём имя шаблона из названия страницы if name == '' or not name then local currentTitleRoot = currentTitle.rootText if not ucFirst and ( ( ru:uc(currentTitleRoot) ~= currentTitleRoot and -- Книга:Литературное наследство, TranslateDate not mw.ustring.match(currentTitleRoot, '^[А-Яа-яA-Za-z]+:?[А-ЯA-Z]') ) or #currentTitleRoot == 1 ) then name = ru:lcfirst(currentTitleRoot) else name = currentTitleRoot end end -- Начинаем собирать код local linkBody, titleObject, linkBegin, linkDivider, linkEnd local prefixes = {} if lang then table.insert(prefixes, lang) end if sister then table.insert(prefixes, sister) end linkBody = table.concat(prefixes, ':') if #linkBody ~= 0 then linkBody = ':' .. linkBody end if mw.ustring.sub(name, 1, 1) ~= ':' then linkBody = linkBody .. ':' end if not global then linkBody = linkBody .. 'Template:' end linkBody = linkBody .. name titleObject = mw.title.new(linkBody) local noLink = noLink or currentTitle == titleObject if not noLink then if not noRedirect or ( noRedirect and not lang and not sister and not titleObject.exists ) then linkBegin = '[[' linkEnd = ']]' linkDivider = '|' else linkBegin = '[' linkEnd = ']' linkDivider = ' ' linkBody = titleObject:fullUrl('redirect=no') end end local text = '' if tag then text = text .. '<' .. tag .. ' class="ts-templateCallCode' if nobr then text = text .. ' nowrap' end text = text .. '"' if style then text = text .. ' style="' .. style .. '"' end text = text .. '>' end if prefix then text = text .. processText(prefix, nowiki) end text = text .. '<span class="' if not spaced then text = text .. ' ts-templateCallCode-opening' end if not black then text = text .. ' ts-templateCallCode-weak' end text = text .. '">{{' if namePrefix then text = text .. namePrefix end text = text .. '</span>' if nav and currentTitle == titleObject then text = text .. '\'\'\'' end text = text .. '<span class="ts-templateCallCode-templateName" data-navboxnavigation-link="0">' local commentedLabel if comment then -- https://phabricator.wikimedia.org/T200704 -- commentedLabel = mw.getCurrentFrame():expandTemplate({title = 'comment', args = {(textInPlaceOfName or name), comment}}) commentedLabel = '<span class="commentedText" title="' .. comment .. '" style="border-bottom: 1px dotted; cursor: help;">' .. (textInPlaceOfName or name) .. '</span>' end local label = (commentedLabel or textInPlaceOfName or name) if not noLink then if noRedirect then text = text .. '<span class="plainlinks">' end text = text .. linkBegin .. linkBody .. linkDivider .. label .. linkEnd if noRedirect then text = text .. '</span>' end else text = text .. label end text = text .. '</span>' if nav and currentTitle == titleObject then text = text .. '\'\'\'' end if not flags.withoutParams then if optpText then text = text .. optpText end text = text .. addParams(args, { spaced = spaced, black = black, nowiki = nowiki, from = from }) if spaced then text = text .. ' ' end end text = text .. '<span class="' if not spaced then text = text .. ' ts-templateCallCode-closing' end if not black then text = text .. ' ts-templateCallCode-weak' end text = text .. '">}}</span>' if postfix then text = text .. processText(postfix, nowiki) end if tag then text = text .. '</' .. tag .. '>' end local ts = mw.getCurrentFrame():extensionTag{ name = 'templatestyles', args = { src = 'Модуль:Template call code/styles.css' } } return ts .. text end function p._onlyParams(args) local yesno = require('Module:Yesno') return addParams(args, { spaced = yesno(args._spaced, false), black = true, nowiki = yesno(args._nowiki, false), from = 1 }) end p.withoutParams = makeInvokeFunc('_main', {withoutParams = true}) p.withParams = makeInvokeFunc('_main', {withoutParams = false}) p.onlyParams = makeInvokeFunc('_onlyParams') return p c4cde66869b509219e9bf629a766ce30ad0bdf97 Модуль:Yesno 828 127 574 297 2024-08-16T15:58:55Z DuOfOrl 5 1 версия импортирована Scribunto text/plain -- Function allowing for consistent treatment of boolean-like wikitext input. -- It works similarly to the template {{yesno}}. return function (val, default) -- If your wiki uses non-ascii characters for any of "yes", "no", etc., you -- should replace "val:lower()" with "mw.ustring.lower(val)" in the -- following line. val = type(val) == 'string' and val:lower() or val if val == nil then return nil elseif val == true or val == 'yes' or val == 'y' or val == 'true' or val == 't' or val == 'да' or val == 'д' -- кириллица or val == 'у' or val == '+' or tonumber(val) == 1 then return true elseif val == false or val == 'no' or val == 'n' or val == 'false' or val == 'f' or val == 'нет' or val == 'н' or val == '-' or tonumber(val) == 0 then return false else return default end end ae94e12a838e770797317ed07b57b330ffeb7658 Модуль:Якорь 828 237 576 575 2024-08-16T15:58:55Z DuOfOrl 5 1 версия импортирована Scribunto text/plain local getArgs = require('Module:Arguments').getArgs local yesno = require('Module:Yesno') local compressSparseArray = require('Module:TableTools').compressSparseArray local p = {} local function add_anchor(anchor, text, visible) local result = mw.html.create('span') :attr('id', anchor) :wikitext(text) if visible then result:addClass('highlight-target') end return tostring(result) end local function unpack(...) local frame = ... local args if type(frame.args) == 'table' then args = getArgs(frame) elseif type(frame) == 'table' then args = frame else args = {...} end return args end function p.main(...) local args = unpack(...) local anchors = compressSparseArray(args) local text local visible = yesno(args.visible or args.v) if visible then text = args.text or args['текст'] or args[1] end local result = text for i, v in ipairs(anchors) do result = add_anchor(anchors[i], result, visible) --[[ создание старого вида якорей для совместимости, см. Обсуждение шаблона:Якорь#Новые html5 ссылки и старые ]] local encoded_anchor = mw.uri.encode(anchors[i], 'WIKI'):gsub('%%', '.') if anchors[i] ~= encoded_anchor then result = add_anchor(encoded_anchor, result, visible) end end return result end return p 2cd9bcc85d4af30c1681bbadfc7d10c60a63e5f2 Шаблон:Ifsubst 10 238 578 577 2024-08-16T15:58:57Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{ {{{|safesubst:}}}#ifeq:{{ {{{|safesubst:}}}NAMESPACE}}|{{NAMESPACE}} |{{{no|{{{2|}}}}}} |{{{yes|{{{1|}}}}}} }}<noinclude> {{Documentation}} </noinclude> 4f51452ff12b7e72ad15c39cba7e3cc7a76b39d4 Шаблон:Optp 10 239 580 579 2024-08-16T15:58:57Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{{{{|safesubst:}}}#invoke: Template call code | onlyParams }}<noinclude>{{doc}}</noinclude> 3e116ca0e893f9ea7b938dae72067678b03bc173 Шаблон:Optp/color 10 240 582 581 2024-08-16T15:58:58Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{{{{|safesubst:}}}ifsubst|1=<!-- --><code style="color: {{optp/color}};">{{{1}}}</code>|2=<!-- --><nowiki>#</nowiki>888888<!-- -->}}<noinclude> [[Категория:Шаблоны:Подстраницы шаблонов]] [[Категория:Шаблоны:Цвет]] [[Категория:Шаблоны:Используемые с подстановкой]] </noinclude> 571a67174168634a24211fe1d5fcaa4727e150f1 Шаблон:Пример 10 241 584 583 2024-08-16T15:58:58Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <includeonly>{{#invoke:Example|main}}</includeonly><noinclude>{{doc}}</noinclude> 6c4efd62aa820f26f326813cddd4cfd909b9bd7a Модуль:Example 828 242 586 585 2024-08-16T15:58:59Z DuOfOrl 5 1 версия импортирована Scribunto text/plain local p = {} -- используется для того, чтобы можно было удалять элементы из таблицы local function copy(other) local res = {} for k,v in pairs(other) do res[k] = v end return res end -- вызов шаблона, при ошибке возвращает пустую строку local function expand(frame, tname, targs) local success, result = pcall( frame.expandTemplate, frame, {title = tname, args = targs} ) if success then return result else return '' end --return frame:expandTemplate({title = tname, args = args}) end --предотвращает обработку вики-текста в отображении образца local function nowiki(str) local res = str str = mw.text.unstripNoWiki(str) str = string.gsub(str, '%[', '&#91;') str = string.gsub(str, '%]', '&#93;') str = string.gsub(str, '<', '&lt;') str = string.gsub(str, '>', '&gt;') str = string.gsub(str, '{', '&#123;') str = string.gsub(str, '|', '&#124;') str = string.gsub(str, '}', '&#125;') str = string.gsub(str, '\'', '&#39;') str = string.gsub(str, '"', '&quot;') str = string.gsub(str, '(://)', '<span>%1</span>') return str end --удаляет из параметров вписанные через HTML-сущности "<nowiki>" и заменяет "{{=}}" на "=" для вызова шаблона local function process_nowiki_equals(str) str = str:gsub('&lt;nowiki>', ''):gsub('&lt;/nowiki>', '') :gsub('&lt;nowiki&gt;', ''):gsub('&lt;/nowiki&gt;', '') :gsub('&#123;&#123;&#61;&#125;&#125;', '=') :gsub('&#123;{&#61;}&#125;', '=') :gsub('{&#123;&#61;&#125;}', '=') :gsub('{{=}}', '=') :gsub('&amp;', '&') return str end function p.main(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end local yesno = require('Module:Yesno') local args = copy(getArgs(frame, {trim = false, removeBlanks = false})) --copy(frame.args) local tag = args._tag local container = args._container or nil local ucFirst = yesno(args._u, false) local link = yesno(args._link, false) local sep = args._sep and args._sep .. ' ' local endl = args._endl or '' local prefix = args._prefix or args['_pre-text'] or '' local postfix = args._postfix or args['_post-text'] or '' local nobr = yesno(args._nobr, false) local spaced = yesno(args._spaced, false) local nocat = yesno(args._nocat, false) local style = args._style if style == '' then style = nil end -- передаётся шаблоном {{стопка примеров}}, один разделитель на все примеры local comment_sep = args._comment_sep -- полезно в шаблоне {{стопка примеров}} (это просто текст в конце) local after = args._after or args._comment -- полезно в шаблоне {{стопка примеров}} (это просто текст в начале) local before = args._before and args._before .. ' ' or '' if style == 'pre' then if not (tag or container) then container = 'pre' end sep = sep or '\n' elseif style == '*pre' then if not (tag or container) then container = '*pre' end sep = sep or '\n' elseif style == 'pre↓' then if not (tag or container) then container = 'pre' end -- содержимое шаблона {{sp↓|50%||-0.5em}} sep = sep or '<div style="margin:-0.5em 50% 0.7em;"><span style="font-size:150%;">↓</span></div>\n' elseif style == '*pre↓' then if not (tag or container) then container = '*pre' end -- содержимое шаблона {{sp↓|50%||-0.5em}} sep = sep or '<div style="margin:-0.5em 50% 0.7em;"><span style="font-size:150%;">↓</span></div>\n' elseif style == 'wikitable' then if not (tag or container) then tag = 'kbd' end sep = sep or '\n| ' comment_sep = '\n| ' end if not (tag or container) then tag = 'code' end if not sep then sep = '→ ' end if not comment_sep then comment_sep = ' &nbsp;' end if (after) then if not style then after = '<small>' .. after .. '</small>' end after = comment_sep .. after end if not after then after = '' end local nwt if tag then nwt = mw.html.create(tag):tag(tag) -- "no-wiki tag", внутри него шаблон не вызывается if nobr then nwt:css('white-space', 'nowrap') end end local content = nowiki(prefix) .. '{{' -- для накопления содержимого тэга local tname = args._template or args[1] if tname == nil then -- если имя шаблона содержит знак "=" (работает, только если нет неименованных параметров) local nextfunc, static, cur = pairs(args) local k, v = nextfunc(static, cur) if k ~= nil and type(k) ~= 'number' and not k:find('^_') then -- именованные параметры, исключая модификаторы внешнего вида tname = k .. "=" .. v args[k] = nil --больше этот параметр нам не пригодится end end if tname == '' or tname == nil then -- при опущенном первом параметре берём имя шаблона из названия страницы local ru = mw.language.new('ru') local currentTitle = mw.title.getCurrentTitle().rootText if not ucFirst and ((ru:uc(currentTitle) ~= currentTitle and -- названия со всеми заглавными буквами not mw.ustring.match(currentTitle, '^[А-Яа-яA-Za-z]+:?[А-ЯA-Z]') -- Книга:Литературное наследство, TranslateDate ) or #currentTitle == 1 ) then tname = ru:lcfirst(currentTitle) else tname = currentTitle end end -- Имя вызываемого шаблона в неименованном первом параметре (или же взято из названия страницы или -- из именованного параметра в отсутствие неименованных — в следующей строчке вреда нет в любом случае), -- больше его обрабатывать не надо if args._template == nil then table.remove(args,1) end if link then content = content .. '[[Шаблон:' .. tname .. '|' .. tname .. ']]' else content = content .. tname end content = content .. endl local targs, equals_pos, param, value, left_shift = {}, 0, '', '', 0 for k, v in pairs(args) do if type(k) == 'number' then -- неименованные параметры equals_pos = v:find('=') if equals_pos and v:find('{{=}}') == equals_pos-2 then equals_pos = nil end if equals_pos then -- содержащие "=" преобразуем в именованные param = v:sub(1, equals_pos-1) value = v:sub(equals_pos+1) targs[param] = process_nowiki_equals(value) content = content .. (spaced and ' ' or '') .. '&#124;' .. nowiki(param) .. '=' .. nowiki(value) .. endl left_shift = left_shift + 1 -- переменная нужна, чтобы квазинумерованные параметры, переданные через "{{=}}", -- не сбивали порядок else -- истинно неименованные targs[k - left_shift] = process_nowiki_equals(v) content = content .. (spaced and ' ' or '') .. '&#124;' .. nowiki(v) .. endl end elseif not k:find('^_') then -- именованные параметры, исключая модификаторы внешнего вида targs[k] = process_nowiki_equals(v) content = content .. (spaced and ' ' or '') .. '&#124;' .. nowiki(k) .. '=' .. nowiki(v) .. endl end end if spaced then content = content .. ' ' end content = content .. '}}' .. nowiki(postfix) if container then local container_args = {} container_args[1] = content nwt = expand(frame, container, container_args) else nwt:wikitext(content):done() end if nocat then targs['nocat'] = 1 end expand_result = tostring(expand(frame, tname, targs)) if expand_result:sub(1, 2) == '{|' then sep = sep .. '\n' end return before .. tostring(nwt) .. ' ' .. sep .. prefix .. expand_result .. postfix .. after end return p bbcc2db5eb699c86d081437122681304ac0c12b8 Шаблон:Str find 10 214 588 477 2024-08-16T15:58:59Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{ {{{|safesubst:}}}#invoke:String|str_find|source={{{1|}}}|{{{2|}}}}}<noinclude> {{doc}} <!-- Add categories and interwikis to the /doc subpage, not here! --> </noinclude> 18d1469d30d27a82ee15fd2fb1ca12a34b5f5e87 Шаблон:= 10 243 590 589 2024-08-16T15:59:00Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki =<noinclude>{{doc}}{{Указание авторства русскоязычной Википедии}}</noinclude> 014d0de3d5673019255be0e21b88cdb2037871db Шаблон:Tc 10 244 592 591 2024-08-16T15:59:01Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{{{{|safesubst:}}}#invoke: Template call code | withParams | _tag = {{{_tag|code}}} }}<noinclude>{{doc}}</noinclude> db6f042f5bfd10e28e4554066fa696babcc884b2 Шаблон:Optp/comment 10 245 594 593 2024-08-16T15:59:01Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <p style="font-size:85%;">Серым {{#ifeq: {{{1|}}} | 1 | показан необязательный параметр | показаны необязательные параметры }}.</p><noinclude> {{doc-inline}} * {{пример|optp/comment}} * {{пример|optp/comment|1}} {{doc-end}} [[Категория:Шаблоны:Подстраницы шаблонов]] </noinclude> 57a6d9eaf58c69ac5e07d5a55c4de17d34d427bf Шаблон:^ 10 246 596 595 2024-08-16T15:59:01Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <div style=margin-top:{{#if:{{{1|}}}|{{{1}}}|2em}}></div><noinclude>{{doc}}<!-- Пожалуйста, добавляйте категории и интервики на страницу документации! --></noinclude> 8a2941bfb74cc487b19b1ce656a0d7b49cfb9a8e Шаблон:Другие названия шаблона 10 247 598 597 2024-08-16T15:59:02Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <includeonly>[[w:ru:ВП:Перенаправления|{{#if:{{{2|}}}|Другие названия|Другое название}}]] этого шаблона{{#if:{{{2|}}}|&#58;|&nbsp;—}} <!-- -->{{#if:{{{1|}}}|{{t|{{{1}}}|noredir}} |<strong class=error>Не указано ни одного альтернативного названия!</strong>}}<!-- -->{{#if:{{{2|}}}|, {{t|{{{2}}}|noredir}} }}<!-- -->{{#if:{{{3|}}}|, {{t|{{{3}}}|noredir}} }}<!-- -->{{#if:{{{4|}}}|, {{t|{{{4}}}|noredir}} }}<!-- -->{{#if:{{{5|}}}|, {{t|{{{5}}}|noredir}} }}<!-- -->{{#if:{{{6|}}}|, {{t|{{{6}}}|noredir}} }}<!-- -->{{#if:{{{7|}}}|, {{t|{{{7}}}|noredir}} }}<!-- -->{{#if:{{{8|}}}|, {{t|{{{8}}}|noredir}} }}<!-- -->{{#if:{{{9|}}}|&#32;[{{fullurl:Служебная:Ссылки сюда/{{FULLPAGENAMEE}}|hidelinks=1&hidetrans=1}} и др.]|{{#if:{{{comment|}}}|&nbsp;({{{comment}}})}}}}.</includeonly><noinclude>{{doc}}{{Указание авторства русскоязычной Википедии}}</noinclude> 7b543dddf959926ff3a8b3d1ae7894515a88b0a0 Шаблон:Abbr/doc 10 248 600 599 2024-08-16T15:59:03Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{docpage}} Этот шаблон выделяет [[w:ru:Аббревиатура|аббревиатуру]] подчёркиванием и добавляет к ней всплывающую подсказку с расшифровкой. Он во многом похож на шаблон {{tl|comment}}. Шаблон может установить ссылку на статью, имя которой — значение 1-го, 2-го или 3-го параметра, например: {{abbr|РФ|Российская Федерация|w:ru:Россия}}. {{днш|аббревиатура|аббр}} == Использование == {{tc||''аббревиатура''|''расшифровка''{{optp|''№ параметра для ссылки или 0, чтобы подавить ссылку''}}}} {{optp/comment}}{{^|1em}} Необязательный третий параметр указывает, какой из параметров использовать для ссылки в качестве названия статьи. * <code>0</code> — подавить ссылку * <code>1</code> (по умолчанию) — использовать 1-й параметр (<code>''аббревиатура''</code>) * <code>2</code> — использовать 2-й параметр (<code>''расшифровка''</code>) * другое — использовать 3-й (этот же) параметр == Примеры == * Ссылка подавлена: : {{пример||ПТЗ|Павлодарский тракторный завод|0}} * Ссылка по умолчанию или явно использует содержимое 1-го параметра: : {{tc||w:ru:АН СССР|Академия наук СССР}}<br><span style="margin-left: 6px;">или</span><br>{{пример||w:ru:АН СССР|Академия наук СССР|1|_sep={{sp↓|||0}}}} <!-- интервики на википедию чтоб не требовало страниц --> * Ссылка использует содержимое 2-го параметра: : {{пример||ПАВ|w:ru:поверхностно-активные вещества|2}} * Ссылка на произвольную страницу в 3-м параметре: : {{пример||ПАВ|поверхностно-активные вещества|w:ru:Психоактивные вещества}} : В данном случае ПАВ расшифровано как «поверхностно-активные вещества», ссылка указывает на статью «[[w:ru:Психоактивные вещества|Психоактивные вещества]]». == Технические ограничения == Технические ограничения те же, что и в шаблоне {{tl|comment}}. * Если в параметрах шаблона есть знак <code>=</code>, то, как и в любом другом шаблоне, приходится использовать явные номера параметров: {{tc|comment|1{{=}}текст|2{{=}}подсказка}}. * В некоторых браузерах длина всплывающей подсказки ограничена. Например, в браузере Mozilla Firefox до третьей версии подсказки были однострочными. * Пользователи [[w:ru:смартфон|смартфонов]] и [[w:ru:Планшетный компьютер|планшетных компьютеров]], как правило, не имеют возможности увидеть всплывающую подсказку, поэтому используйте данный шаблон только там, где это действительно необходимо. <includeonly> [[Категория:Шаблоны:Форматирование]] [[Категория:Шаблоны:Внутренние ссылки]] </includeonly> 060aec5d84b5320d02f9c95e1cd0427e110f1315 Шаблон:Sp↓ 10 249 602 601 2024-08-16T15:59:04Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <div style="margin-left:{{#if: {{{1|}}} | {{{1}}} | 1.3em }}; {{#if: {{{2|}}} | margin-top:{{{2}}}; }} margin-bottom:{{#if: {{{3|}}} | {{{3}}} | 0.7em }};"><span style="font-size:{{#if: {{{size|}}} | {{{size}}} | {{#ifeq: {{str find|{{{1|}}}|%}} | -1 | 120% | 150% }} }};">↓</span></div><noinclude>{{doc}}</noinclude> e0d0479cdd64d3e90be2c1c2d1b3c3502312f926 Шаблон:Днш 10 250 604 603 2024-08-16T15:59:04Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki #REDIRECT [[Шаблон:Другие названия шаблона]] 310154c4badc00ae3faf727456b5aba85e337ba6 Шаблон:Карточка 10 129 606 502 2024-08-16T16:10:59Z DuOfOrl 5 wikitext text/x-wiki <table class="infobox {{{класс_тела|}}}" style="{{{стиль_тела|}}}" {{#if:{{{имя|}}}|{{#ifeq:{{{имя|}}}|-||data-name="{{{имя}}}"}}}}><!-- Вверху0 -->{{#if:{{{вверху0|}}}|<tr><td colspan="2" class="{{{класс_вверху0|}}}" style="text-align:center; {{{стиль_вверху0|}}}">{{{вверху0}}}</td></tr>}}<!-- Вверху -->{{#if:{{{вверху|}}}|<tr><th colspan="2" class="infobox-above {{{класс_вверху|}}}" style="{{{стиль_вверху|}}}">{{{вверху}}}</th></tr>}}<!-- Вверху2 -->{{#if:{{{вверху2|}}}|<tr><td colspan="2" class="{{{класс_вверху2|}}}" style="text-align:center; {{{стиль_вверху2|}}}">{{{вверху2}}}</td></tr>}}<!-- Вверху3 -->{{#if:{{{вверху3|}}}|<tr><td colspan="2" class="{{{класс_вверху3|}}}" style="text-align:center; {{{стиль_вверху3|}}}">{{{вверху3}}}</td></tr>}}<!-- Изображение -->{{#if:{{{изображение|}}}|<tr><td colspan="2" class="infobox-image {{{класс_изображения|}}}" style="{{{стиль_изображения|}}}"> {{{изображение}}} {{#if:{{{подпись|}}}| <div class="media-caption" style="{{{стиль_подписи|}}}">{{{подпись}}}</div>}}</td></tr>}}<!-- Изображение2 -->{{#if:{{{изображение2|}}}|<tr><td colspan="2" class="infobox-image {{{класс_изображения2|}}}" style="{{{стиль_изображения2|}}}"> {{{изображение2}}} {{#if:{{{подпись2|}}}| <div class="media-caption" style="{{{стиль_подписи2|}}}">{{{подпись2}}}</div>}}</td></tr>}}<!-- Изображение3 -->{{#if:{{{изображение3|}}}|<tr><td colspan="2" class="infobox-image {{{класс_изображения3|}}}" style="{{{стиль_изображения3|}}}"> {{{изображение3}}} {{#if:{{{подпись3|}}}| <div class="media-caption" style="{{{стиль_подписи3|}}}">{{{подпись3}}}</div>}}</td></tr>}}<!-- Строки -->{{#invoke:Infobox|renderLines}}<!-- Внизу -->{{Карточка/внизу| стиль_внизу_общий={{{стиль_внизу|}}}| класс_внизу={{{класс_внизу|}}}| внизу={{{внизу|}}}}}<!-- Внизу N -->{{#invoke:Transclude|npc|Карточка/внизу| стиль_внизу_общий={{{стиль_внизу|}}}| стиль_внизу=| класс_внизу=| внизу=}} </table><includeonly><!-- статьи -->{{#if:{{NAMESPACE}}||<!-- -->{{#if:{{{имя|}}}||[[Категория:Статьи с шаблонами-карточками без имени]]}}<!-- -->{{#ifeq:{{{имя|}}}|{{subst:PAGENAME}}|[[Категория:Статьи с шаблонами-карточками без имени]]}}<!-- -->}}<!-- шаблоны -->{{#ifeq:{{NAMESPACENUMBER}}|10|<!-- -->{{#if:{{{имя|}}}||[[Категория:Шаблоны-карточки без имени]]}}<!-- -->{{#ifeq:{{{имя|}}}|{{subst:PAGENAME}}|[[Категория:Шаблоны-карточки без имени]]}}<!-- -->{{#if:{{{название|}}}{{{стиль_названия|}}}|[[Категория:Шаблоны с использованием параметра «название» в шаблоне «Карточка»]]}}<!-- -->{{#if:{{{подпись|}}}{{{стиль_подписи|}}}{{{подпись2|}}}{{{стиль_подписи2|}}}{{{подпись3|}}}{{{стиль_подписи3|}}}|[[Категория:Шаблоны с использованием параметра «подпись» в шаблоне «Карточка»]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_тела|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_названия|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_вверху|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_вверху2|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_вверху3|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_подписи|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_подписи2|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_подписи3|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_заголовков|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_меток|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_текста|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_внизу|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifeq:{{{имя|}}}|{{PAGENAME}}| [[Категория:Шаблоны-карточки по алфавиту|{{ucfirst:{{без начала|{{PAGENAME}}|Карточка }}}}]]}}<!-- -->}}<!-- любое пространство имён -->{{#if:{{{название|}}}{{{стиль_названия|}}}|[[Категория:Страницы с использованием параметра «название» в шаблоне «Карточка»]]}}<!-- -->{{#if:{{{подпись|}}}{{{стиль_подписи|}}}{{{подпись2|}}}{{{стиль_подписи2|}}}{{{подпись3|}}}{{{стиль_подписи3|}}}|[[Категория:Страницы с использованием параметра «подпись» в шаблоне «Карточка»]]}}</includeonly><noinclude>{{doc}}{{Указание авторства русскоязычной Википедии}}</noinclude> 8b14ccc682362e6ed5a194621133805aea17ab0d Модуль:No globals 828 251 608 607 2024-08-16T16:17:36Z DuOfOrl 5 1 версия импортирована Scribunto text/plain local mt = getmetatable(_G) or {} function mt.__index (t, k) if k ~= 'arg' then error('Tried to read nil global ' .. tostring(k), 2) end return nil end function mt.__newindex(t, k, v) if k ~= 'arg' then error('Tried to write global ' .. tostring(k), 2) end rawset(t, k, v) end setmetatable(_G, mt) 8ce3969f7d53b08bd00dabe4cc9780bc6afd412a Шаблон:Ombox 10 20 610 425 2024-08-16T16:22:34Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{#invoke:Message box|ombox}}<noinclude> {{doc}}<!-- Add categories and interwikis to the /doc subpage, not here! --></noinclude> ab34435c5ebc29de589c9b059e88da5d0e6f16e4 Модуль:Calendar 828 62 612 97 2024-08-16T16:22:38Z DuOfOrl 5 1 версия импортирована Scribunto text/plain local p = {} -- Необходимые модули и переменные local getArgs = require('Module:Arguments').getArgs local yesno = require('Module:Yesno') local mwlang = mw.getContentLanguage() local err = "―" -- NthDay nil result local tCon = table.concat -- 00) Блок многократно используемых списков local bool_to_number={ [true]=1, [false]=0 } local monthlang = {"января","февраля","марта","апреля","мая","июня","июля","августа","сентября","октября","ноября","декабря"} local month_to_num = {["января"]=1,["февраля"]=2,["марта"]=3,["апреля"]=4,["мая"]=5,["июня"]=6, ["июля"]=7,["августа"]=8,["сентября"]=9,["октября"]=10,["ноября"]=11,["декабря"]=12,["-"]=""} local monthd = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} local params = { {"г", "g"}, {"ю", "j"}} local comment = { '<span style="border-bottom: 1px dotted; cursor: help" title="по юлианскому календарю">','</span>'} -- duplicates: -- AST, BST, CST, ECT, IST, MST, PST, SST, local known_tzs = { ACDT='+10:30', ACST='+09:30', ACT ='+08:00', ADT ='-03:00', AEDT ='+11:00', AEST='+10:00', AFT ='+04:30', AKDT='-08:00', AKST ='-09:00', AMST ='+05:00', AMT ='+04:00', ART ='-03:00', AST ='+03:00', AST ='+04:00', AST ='+03:00', AST ='-04:00', AWDT='+09:00', AWST='+08:00', AZOST='-01:00', AZT ='+04:00', BDT ='+08:00', BIOT='+06:00', BIT ='-12:00', BOT ='-04:00', BRT ='-03:00', BST ='+06:00', BST ='+01:00', BTT ='+06:00', CAT ='+02:00', CCT ='+06:30', CDT ='-05:00', CEDT='+02:00', CEST='+02:00', CET ='+01:00', CHAST='+12:45', CIST='-08:00', CKT ='-10:00', CLST='-03:00', CLT ='-04:00', COST ='-04:00', COT ='-05:00', CST ='-06:00', CST ='+08:00', CVT ='-01:00', CXT ='+07:00', CHST='+10:00', DFT ='+01:00', EAST='-06:00', EAT ='+03:00', ECT ='-04:00', ECT ='-05:00', EDT ='-04:00', EEDT='+03:00', EEST ='+03:00', EET ='+02:00', EST ='-05:00', FJT ='+12:00', FKST='-03:00', FKT ='-04:00', GALT ='-06:00', GET ='+04:00', GFT ='-03:00', GILT='+12:00', GIT ='-09:00', GMT ='+00:00', GST ='-02:00', GYT ='-04:00', HADT='-09:00', HAST ='-10:00', HKT ='+08:00', HMT ='+05:00', HST ='-10:00', IRKT='+08:00', IRST ='+03:30', IST ='+05:30', IST ='+01:00', IST ='+02:00', JST ='+09:00', KRAT ='+07:00', KST ='+09:00', LHST='+10:30', LINT='+14:00', MAGT='+11:00', MDT ='-06:00', MIT ='-09:30', MSD ='+04:00', MSK ='+03:00', MST ='+08:00', MST ='-07:00', MST ='+06:30', MUT ='+04:00', NDT ='-02:30', NFT ='+11:30', NPT ='+05:45', NST ='-03:30', NT ='-03:30', OMST='+06:00', PDT ='-07:00', PETT ='+12:00', PHOT ='+13:00', PKT ='+05:00', PST ='-08:00', PST ='+08:00', RET ='+04:00', SAMT ='+04:00', SAST='+02:00', SBT ='+11:00', SCT ='+04:00', SLT ='+05:30', SST ='-11:00', SST ='+08:00', TAHT='-10:00', THA ='+07:00', UTC ='+00:00', UYST ='-02:00', UYT ='-03:00', VET ='-04:30', VLAT='+10:00', WAT ='+01:00', WEDT ='+01:00', WEST='+01:00', WET ='+00:00', YAKT='+09:00', YEKT ='+05:00', -- US Millitary (for RFC-822) Z='+00:00', A='-01:00', M='-12:00', N='+01:00', Y='+12:00', } local category = { ["no_parameters"]= "<!--[[Категория:Модуль:Calendar:Страницы без параметров]]-->", ["incomplete_parameters"]= "<!--[[Категория:Модуль:Calendar:Страницы с неполными или некорректными параметрами]]-->", ["without_verification"]= "<!--[[Категория:Модуль:Calendar:Страницы без проверки параметров]]-->", ["erroneous_parameters"]= "<!--[[Категория:Модуль:Calendar:Страницы с ошибочными параметрами]]-->" } -- несколько параметров передаются вместе с кодом ошибки в таблице, один может быть передан простым значением local e = { ["start"]="<span class=error>Ошибка: ", ["ending"]=".</span>", ["no_pattern_match"]="строка «%s» не совпадает с заданными паттернами", ["no_valid_date"]="дата «%s» не является корректной", ["wrong_jd"]="юлианская дата %s вне диапазона", ["no_data"]="нет входящих данных", ["too_many_arguments"]="ожидается менее %i аргументов", ["too_little_arguments"]="ожидается более %i аргументов", ["wrong_calculation"]="даты %s и %s не прошли проверку, %s дней разница", ["unknown_param"]="параметр %s неизвестен", ["unknown_error"]="неизвестная ошибка", ["tech_error"]="ошибка в функции %s", ["box_date"]="строка «%s» не является верной датой, пожалуйста, укажите дату в формате ГГГГ-ММ-ДД" -- [""]="", } local tzs_names = {"ACDT","ACST","ACT","ADT","AEDT","AEST","AFT","AKDT","AKST", "AMST","AMT","ART","AST","AST","AST","AST","AWDT","AWST","AZOST","AZT","BDT", "BIOT","BIT","BOT","BRT","BST","BST","BTT","CAT","CCT","CDT","CEDT","CEST", "CET","CHAST","CIST","CKT","CLST","CLT","COST","COT","CST","CST","CVT","CXT", "CHST","DFT","EAST","EAT","ECT","ECT","EDT","EEDT","EEST","EET","EST","FJT", "FKST","FKT","GALT","GET","GFT","GILT","GIT","GMT","GST","GYT","HADT","HAST", "HKT","HMT","HST","IRKT","IRST","IST","IST","IST","JST","KRAT","KST","LHST", "LINT","MAGT","MDT","MIT","MSD","MSK","MST","MST","MST","MUT","NDT","NFT", "NPT","NST","NT","OMST","PDT","PETT","PHOT","PKT","PST","PST","RET","SAMT", "SAST","SBT","SCT","SLT","SST","SST","TAHT","THA","UTC","UYST","UYT","VET", "VLAT","WAT","WEDT","WEST","WET","YAKT","YEKT","Z","A","M","N","Y","MSK"} local pattern = { -- для распознавания дат, переданных одним строчным параметром {"(-?%d%d%d%d?)[-%.%s/\\](%d%d)[-%.%s/\\](%d%d)", ["order"] = {3,2,1} }, -- yyyy mm dd {"(%d+)[-%.%s/\\](%d+)[-%.%s/\\](%d%d%d%d?)", ["order"] = {1,2,3} }, -- dd mm yyyy {"(%d%d)[-%.%s/\\](%d%d%d%d?)", ["order"] = {2,3} }, -- mm yyyy {"(%d%d%d%d?)[-%.%s/\\](%d%d)", ["order"] = {3,2} }, -- yyyy mm {"(%d+)%s(%l+)%s(%d%d%d%d?)", ["order"] = {1,2,3} }, -- d mmm y {"(%l+)%s(%d+),?%s(%d%d%d%d?)", ["order"] = {2,1,3} }, -- mmm d, y {"(%l+)%s(%d%d%d%d?)", ["order"] = {2,3} }, -- mmm y } local time_units = {"year","month","day"} --не используется --[[ local time_units = {"second", "minute", "hour", "day_of_month", "day_of_week", "day_of_year", "week", "month", "year", "year_of_century", "century"} ]]-- -- напоминание чтобы сделать более точные пересчёты - с часами / расчёт длительностей периодов local mnlang = {"ru_G", "ru_N", "en", "en_S", "de", "fr"} local month_lang = { ["ru_G"] = {"января","февраля","марта","апреля","мая","июня", "июля","августа","сентября","октября","ноября","декабря"}, ["ru_N"] = {"январь","февраль","март","апрель","май","июнь", "июль","август","сентябрь","октябрь","ноябрь","декабрь"}, ["en"] = {"january", "february", "march", "april", "may", "june", "july", "august", "september", "october", "november", "december"}, ["en_S"] = {"jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec"}, ["de"] = {"januar", "februar", "märz", "april", "mai", "juni", "juli", "august", "september", "oktober", "november", "dezember"}, ["fr"] = {"janvier", "février", "mars", "avril", "mai", "juin", "juillet", "août", "septembre", "octobre", "novembre", "décembre"} } -- заполняется автоматически local reverse_month_lang = {} -- вспомогательная функция для обращения таблиц (смена ключей со значениями) local reverse_table = function (strait_table) local reversed_table = {} for k,v in pairs(strait_table) do reversed_table[v] = k end return reversed_table end -- запуск цикла по заполнению обратных таблиц, необходимых для распознавания дат local filling_months = function (mnlang, month_lang) for i=1, #mnlang do reverse_month_lang[mnlang[i]] = reverse_table(month_lang[mnlang[i]]) end end -- 10) Блок общих функций local function trim(str) if not str then return nil else return str:match'^()%s*$' and '' or str:match'^%s*(.*%S)' end end local function purif(str) if str == "" or str == nil then return nil elseif type(tonumber(str)) == "number" then return math.floor(tonumber(str)) else return nil end -- need .5 -- ,5 number format converter? end local function is(str) if (not str) or (str == "") then return false else return yesno(str,false) end end local function init(num) local output = {} for i=1,num do table.insert(output, {["year"]="", ["month"]="", ["day"]=""}) end return unpack(output) end local function isyear(tbl) if type(tbl) ~= 'table' then return false elseif not tbl["year"] then return false elseif type(tbl["year"]) == 'number' then return true else return false end end local function inbord(val, down, up) return not (type(up) ~= "number" or type(down) ~= "number" or type(val) ~= "number" or up < down or val < down or val > up) end local function shallowcopy(orig) local orig_type = type(orig) local copy if orig_type == 'table' then copy = {} for orig_key, orig_value in pairs(orig) do copy[orig_key] = orig_value end else -- number, string, boolean, etc copy = orig end return copy end local inlist = function ( var, list ) local n = #list local inlist = false for i=1,n do if var == list[i] then inlist = true end end return inlist end -- 20) Блок общих проверочных функций, связанных с датами local function unwarp(tbl) if not tbl then return "" elseif type(tbl) ~= "table" then return tbl elseif (tbl.day or tbl.month or tbl.year) then return (tbl.year or "?").."-"..(tbl.month or "?").."-"..(tbl.day or "?") else return (tbl[3] or "?").."-"..(tbl[2] or "?").."-"..(tbl[1] or "?") end end local function leap_year(y,jul) if (not y) or (type(y) ~= "number") then return false elseif (y % 4) ~= 0 then return false elseif not jul and (y % 100 == 0 and y % 400 ~= 0) then return false else return true end end -- функция для вычисления последнего дня месяца для юлианского и григорианского календарей local function month_end_day (month,year,is_julian) local month_end_day = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} -- если не задан год, дата 29 февраля считается допустимой if not month or type(month) ~= "number" or month < 1 or month > 12 then return nil elseif month ~= 2 or not year then return month_end_day[month] elseif month == 2 and (year % 4) == 0 and not ((not is_julian) and (year % 100 == 0 and year % 400 ~= 0)) then return 29 elseif month == 2 then return 28 else return nil -- в случае не целого значения входящих параметров или при иных непредусмотренных событиях end end local function isdate ( chain , jul ) -- можно использовать для проверки таблиц с полями day, month, year if not chain then return false elseif (not type(chain) == "table") or (not inbord(chain.year,-9999,9999)) or (not inbord(chain.month,1,12)) or (not inbord(chain.day,1,31)) or chain.day > monthd[chain.month] -- or chain.year == 0 then return false elseif chain.month == 2 and chain.day == 29 and not leap_year(chain.year,jul) then return false else return true end -- check for other calendars needed? end local function ispartdate ( chain ) if not chain then return false elseif not (type(chain) == "table") then return false elseif (inbord(chain.year,-9999,9999) or inbord(chain.month,1,12) or inbord(chain.day,1,31)) then return true else return false end -- partial date -- more detailed check for 31.02.0000 needed -- check for other calendars needed end -- from date1 to date2 in one year (beetwen jan-dec, dec-jan needed) local function partdist(date1,date2) local mont, dist = 0, 0 local d1d, d1m, d2d, d2m = (date1["day"] or ""), (date1["month"] or ""),(date2["day"] or ""), (date2["month"] or "") if not (inbord(d1d,1,31) and inbord(d2d,1,31)) then return false end -- нужна доп. проверка частичных дат на корректность if (inbord(d1m,1,12) or inbord(d2m,1,12)) and (d1m == "" or d2m == "") then mont = purif(date1["month"] or date2["month"]) d1m, d2m = mont, mont end -- mw.log("📏 day: " ..d1d .."->"..d2d.." month: ".. d1m.."->"..d2m ) if (inbord(d1m,1,12) and d1d <= monthd[d1m]) and (inbord(d2m,1,12) and d2d <= monthd[d2m]) then if d2m == d1m then dist = d2d - d1d else dist = monthd[d1m] - d1d + d2d end return dist else return math.huge end end local function dmdist(d1,d2) local p1,p2 = math.huge,math.huge if not not partdist(d1,d2) then p1=partdist(d1,d2) end if not not partdist(d2,d1) then p1=partdist(d2,d1) end -- if (not p1) or (not p2) then -- return (p1 or "") .. (p2 or "") -- else -- mw.log("d1, d2 = " .. undate(d1) .. ", " .. undate(d2)) return math.min(tonumber(partdist(d1,d2)) or math.huge,tonumber(partdist(d2,d1)) or math.huge) -- end end -- 30) Блок функций для обработки ввода-вывода дат local function undate(tbl) if not tbl then return "" else return (tbl.year or "").."-"..(tbl.month or "").."-"..(tbl.day or "") end end -- функция для нормализации значений дат и перевода месяцев в числа local function numerize(str) if type(str) == "number" then return math.floor(str) elseif str == "" or str == nil or type(str) ~= "string" then return nil elseif type(tonumber(str)) == "number" then return math.floor(tonumber(str)) else for i=1, #mnlang do if inlist(mw.ustring.lower(str),month_lang[mnlang[i]]) then return reverse_month_lang[mnlang[i]][mw.ustring.lower(str)] end end end end -- функция распознавания даты, переданной одной строкой local function parse_date(date_string) if type(date_string) ~= "string" or date_string == "" then return nil end local out_date_str = {"","",""} local error_data = {} for i=1, #pattern do local result_1, result_2, result_3 = mw.ustring.match(mw.ustring.lower(date_string),pattern[i][1]) if (result_1 or "") > "" then out_date_str[pattern[i].order[1]] = result_1 out_date_str[pattern[i].order[2]] = result_2 if (pattern[i].order[3]) then out_date_str[pattern[i].order[3]] = result_3 end -- mw.log("Паттерн " .. i .. ", строка: " .. date_string) break end end local date = { ["day"] =numerize(out_date_str[1]), ["month"]=numerize(out_date_str[2]), ["year"] =numerize(out_date_str[3])} return date --, error_data end ----[[ УСТАРЕЛО ]]---- local numstr2date = function(numstr) local format = "Y-m-d" local iso_date = mwlang:formatDate(format,numstr) local y,m,d = string.match(iso_date, "(%d+)-(%d+)-(%d+)") local dateout = {["year"]=purif(y), ["month"]=purif(m), ["day"]=purif(d)} return dateout end --local numstr2date = function(numstr) -- local nums = {} -- local dateout = {} -- for num in string.gmatch(numstr,"(%d+)") do -- table.insert(nums,purif(num)) -- end -- if #nums ~= 3 then error("В поле даты вместо трёх чисел с разделителями указано " .. #nums) -- elseif not inbord(nums[2],1,12) then error("Месяц с номером " .. nums[2] .. " не найден") -- elseif not inbord(nums[3],1,31) then -- dateout = {["year"]=nums[3], ["month"]=nums[2], ["day"]=nums[1]} -- elseif not inbord(nums[1],1,31) then -- dateout = {["year"]=nums[1], ["month"]=nums[2], ["day"]=nums[3]} -- elseif inbord(nums[1],1,31) then -- dateout = {["year"]=nums[3], ["month"]=nums[2], ["day"]=nums[1]} -- else -- local mwlang = mw.getContentLanguage() -- implement mwlang:formatDate(format,datein,true) here -- return error("Не распознано " .. numstr .. " как дата") -- end -- return dateout --end local function year2lang(numyear,yearmark,wiki) if not numyear then return "" end if not yearmark then yearmark = "" end local output = "" local bcmark = " до н. э." if numyear > 0 then bcmark = "" else numyear = 1 - numyear end if wiki then -- output = tCon({'[[', numyear,' год',bcmark,'|', numyear,']]', " ", yearmark, " ", bcmark}) output = tCon({'[[', numyear,' год',bcmark,'|', trim(numyear .. " " .. yearmark .. " " .. bcmark), ']]'}) else output = tCon({numyear, " ", yearmark, bcmark}) end return trim(output) end local function day2lang(datein,wikidate,wiki,inner_brt) -- if not isdate(wikidate) then wiki = false end if not ispartdate(datein) then return "" end local dm_separ, output = "", nil if (not (not datein.day)) and (not (not datein.month)) then dm_separ = " " end if (not datein.month) then datein.month = "" end if (not datein.day) then datein.day = "" end local monlan = monthlang[datein.month] or "" if wiki and not inner_brt then output = tCon({"[[", wikidate.day, " ", monthlang[wikidate.month] or "", "|", (datein.day or ""), dm_separ, monlan, "]]"}) elseif wiki then output = tCon({"[[", wikidate.day, " ", monthlang[wikidate.month] or "", "|", (datein.day or ""), dm_separ, monlan}) else output = tCon({datein.day, dm_separ, monlan}) end return trim(output) end local function triple_txt2date(d,m,y) -- добавить (args[1]:match("(%a+)") or "-") для нестандартной записи -- mw.ustring.match((m or ""),"(%a+)") local msg = "" local year = purif((y or "-"):match("(%d+)")) local month = purif(month_to_num[string.lower(mw.ustring.match((m or ""),"(%a+)"))]) local day = purif((d or "-"):match("(%d+)")) if not month then msg = category.incomplete_parameters month = purif(month_to_num[string.lower(mw.ustring.match((d or ""),"(%a+)") or "-")]) end if (not day) and ((purif(string.match(m or "","(%d+)") or "") or 32) <= (monthd[month] or 31)) then msg = category.incomplete_parameters day = purif(m:match("(%d+)") or "") end if not year then msg = category.incomplete_parameters year = purif(string.match(m or "","(%d+)") or "") end local dateout = {["year"]=year, ["month"]=month, ["day"]=day, ["msg"]=msg} return dateout end local function glue(d1,m1,y1,d2,m2,y2) if (not d1) and (not m1) and (not y1) and (not d2) and (not m2) and (not y2) then return category.incomplete_parameters end local gd,gm,gy,jd,jm,jy = (d1 or ""), (m1 or ""), (y1 or ""), (d2 or ""), (m2 or ""), (y2 or "") --mw.log(tCon({gd,gm,gy,jd,jm,jy})) local gm_sep = {" [["," год|","]]"} if (not gy) or (gy == "") then gm_sep = {"","",""} end return tCon({comment[1],trim(trim(jd .. " " .. jm) .. " " .. jy ), comment[2]," ([[",trim(gd .. " " .. gm),"]]",gm_sep[1],(gy:match("(%d+)") or ""), gm_sep[2],gy,gm_sep[3],")",category.incomplete_parameters}) end -- добавить отображение без года local function double_couple(jdate, gdate, wd, wm, wy, sq_brts, yearmark) local msg = "" msg = (jdate.msg or "") .. (gdate.msg or "") local cd = {} local jd = shallowcopy(jdate) local gd = shallowcopy(gdate) local left = "(" local right = ")" if sq_brts then left = "&#091;" right = "&#093;" end if (not isdate(jdate,true)) then return error((jdate.day or "") .. "." .. (jdate.month or "") .."." .. (jdate.year or "") .. " неподходящая дата") elseif (not isdate(gdate)) then return error((gdate.day or "") .. "." .. (gdate.month or "") .."." .. (gdate.year or "") .. " неподходящая дата") end if jd.year == gd.year then cd.year = gd.year gd.year, jd.year = nil, nil end if jd.month == gd.month then cd.month = gd.month gd.month, jd.month = nil, nil end if (not not cd.month) and wm then return tCon({comment[1] .. trim(day2lang(jd,jdate,false) .. " " .. year2lang(jd.year,yearmark,false)) .. comment[2], trim(left .. day2lang(gd,gdate,wd,wm) .. " " .. year2lang(gd.year,yearmark,wy)) .. right, day2lang(cd,gdate,false) .. "]]", trim(year2lang(cd.year,yearmark,wy)..msg)}, " ") end return tCon({comment[1] .. trim(day2lang(jd,jdate,false) .. " " .. year2lang(jd.year,yearmark,false)) .. comment[2], trim(left .. day2lang(gd,gdate,wd) .. " " .. year2lang(gd.year,yearmark,wy)) .. right, trim(day2lang(cd,gdate,false)), trim(year2lang(cd.year,yearmark,wy)..msg)}, " ") end -- 40) Блок функций для перевода дат с использованием [[Юлианская дата]] local function gri2jd( datein ) if not isdate(datein) then return error((datein.day or "") .. "." .. (datein.month or "") .."." .. (datein.year or "") .. " неподходящая дата") end local year = datein.year local month = datein.month local day = datein.day -- jd calculation local a = math.floor((14 - month)/12) local y = year + 4800 - a local m = month + 12*a - 3 local offset = math.floor(y/4) - math.floor(y/100) + math.floor(y/400) - 32045 local jd = day + math.floor((153*m + 2)/5) + 365*y + offset -- jd validation local low, high = -1931076.5, 5373557.49999 if not (low <= jd and jd <= high) then return error((datein.day or "") .. "." .. (datein.month or "") .. "." .. (datein.year or "") .. " выходит за пределы разрешённого диапазона") end return jd end local function jd2jul( jd ) if type(jd) ~= "number" then return error("Промежуточная переменная " .. (jd or "") .. " не является числом") end -- calendar date calculation local c = jd + 32082 local d = math.floor((4*c + 3)/1461) local e = c - math.floor(1461*d/4) local m = math.floor((5*e + 2)/153) local year_out = d - 4800 + math.floor(m/10) local month_out = m + 3 - 12*math.floor(m/10) local day_out = e - math.floor((153*m + 2)/5) + 1 -- output local dateout = {["year"]=year_out, ["month"]=month_out, ["day"]=day_out} return dateout end local function jul2jd( datein ) if not isdate(datein,true) then return error((datein.day or "") .. "." .. (datein.month or "") ..".".. (datein.year or "") .. " неподходящая дата") end local year = datein.year local month = datein.month local day = datein.day -- jd calculation local a = math.floor((14 - month)/12) local y = year + 4800 - a local m = month + 12*a - 3 local offset = math.floor(y/4) - 32083 local jd = day + math.floor((153*m + 2)/5) + 365*y + offset -- jd validation local low, high = -1930999.5, 5373484.49999 if not (low <= jd and jd <= high) then return error((datein.day or "") .. "." .. (datein.month or "") .."." .. (datein.year or "") .. " выходит за пределы разрешённого диапазона") end return jd end local function jd2gri( jd ) if type(jd) ~= "number" then return error("Промежуточная переменная " .. (jd or "") .. " не является числом") end -- calendar date calculation local a = jd + 32044 local b = math.floor((4*a + 3) / 146097) local c = a - math.floor(146097*b/4) local d = math.floor((4*c+3)/1461) local e = c - math.floor(1461*d/4) local m = math.floor((5*e+2)/153) local day_out = e - math.floor((153*m+2)/5)+1 local month_out = m + 3 - 12*math.floor(m/10) local year_out = 100*b + d - 4800 + math.floor(m/10) -- output local dateout = {["year"]=year_out, ["month"]=month_out, ["day"]=day_out} return dateout end local function astroyear(num, bc) if not num then return error() elseif type(num) ~= "number" then return error() end if num < 1 then return num end if not bc then return num else return 1 - num end end local function recalc(datein,calend) if inlist(calend,params[1]) then return jd2jul(gri2jd(datein)), datein elseif inlist(calend,params[2]) then return datein, jd2gri(jul2jd(datein)) else error("Параметр " .. (calend or "") .. " не опознан, разрешённые: " .. tCon(params[1]," ") .. " и " .. tCon(params[2]," ")) end end -- 50) Функции для обработки UTC local function utc(str,margin) local d = 1 local dchar = "+" local beginning = "[[UTC" local ending = "]]" local cat = "" local nums = {} local hmarg, timedec = 0, 0 local mmarg = "00" local output = "" -- checking type of input if not margin then margin = 0 elseif type(tonumber(margin)) ~= 'number' then output = "Can't shift by " .. margin error(output) end if type(str) ~= 'string' then error("Нет входящей строки") elseif str:byte(1) == 43 then elseif inbord(str:byte(1),48,57) then cat = "[[Категория:Википедия:Ошибка в часовом поясе НП]]" elseif str:byte(1) == 45 or string.sub(str,1,3) == "−" or string.sub(str,1,1)=="-" then d = -1 else error(string.char(str:byte(1)) .. " недопустимый первый символ") end -- parsing input for num in string.gmatch(str,"(%d+)") do table.insert(nums,purif(num)) end if #nums > 2 then error("Ожидается всего 2 числа, а не " .. #nums) elseif #nums == 0 then error("Необходимо что-то ввести") elseif #nums == 1 then if inbord(nums[1],0,14) then timedec = d*nums[1] + margin else error("Только часы от -14 до 14") end elseif #nums == 2 then if not inbord(nums[1],0,14) then error("Только часы от -14 до 14") elseif not inbord(nums[2],0,59) then error("Минуты только от 0 до 59") else timedec = d*(nums[1] + nums[2]/60) + margin end end if tonumber(timedec) == purif(timedec) then hmarg = timedec else local h, m = math.modf(math.abs(timedec)) hmarg = h mmarg = math.floor(m*60) end if timedec == 0 then dchar = "±" elseif timedec > 0 then elseif timedec < 0 then dchar = "&minus;" end -- output output = beginning .. dchar .. math.abs(hmarg) .. ":" .. string.format("%02d",mmarg) .. ending .. cat return output end -- 60) Блок функций ввода-вывода function p.NthDay( frame ) local args = getArgs(frame, { frameOnly = true }) local num, wday, mont, yea, format = purif(args[1]), purif(args[2]), purif(args[3]), purif(args[4]), args[5] if not format then format = "%d.%m.%y" end if not inbord(num,-5,5) then return error("The number must be between -5 and 5") elseif num == 0 then return error("The number must not be zero") end if not inbord(wday,0,6) then return error("The day of the week must be between 0 and 6") end if not inbord(mont,1,12) then return error("The month must be between 1 and 12") end if not inbord(yea,0,9999) then return error("Wrong year number") end if inbord(num,1,5) then local m_start = os.time{year=yea, month=mont, day=1, hour=0} local m_wds = tonumber(os.date("%w", m_start)) local start_shift = ( (num - bool_to_number[wday >= m_wds]) * 7 - (m_wds - wday) ) * 24 * 60 * 60 local tim = m_start + start_shift if tonumber(os.date("%m", tim)) == mont then return (os.date(format, tim)) else return (err) end elseif inbord(num,-5,-1) then local m_end = os.time{year = yea, month = mont + 1, day = 1, hour = 0} - 24 * 60 * 60 local m_wde = tonumber(os.date("%w", m_end)) local end_shift = ((math.abs(num + 1) + bool_to_number[wday > m_wde]) * 7 + (m_wde - wday)) * 24 * 60 * 60 local tim = m_end - end_shift if tonumber(os.date("%m", tim)) == mont then return (os.date(format, tim)) else return (err) end end end -- =p.ToIso(mw.getCurrentFrame():newChild{title="smth",args={"12 декабря 2020"}}) -- =p.ToIso(mw.getCurrentFrame():newChild{title="smth",args={"1.2.1602"}}) -- =p.ToIso(mw.getCurrentFrame():newChild{title="smth",args={"12.12.2021"}}) -- =p.ToIso(mw.getCurrentFrame():newChild{title="smth",args={"2021.12.12"}}) function p.ToIso( frame ) local args = getArgs(frame, { frameOnly = true }) local datein = args[1] -- инициализация, заполнение обратных таблиц, копирование параметров filling_months(mnlang, month_lang) -- парсинг входящей даты по шаблону local date = parse_date(datein) if not (type(date.year) == 'number') then return ("Wrong year: " .. unwarp(date)) end if not (1 <= date.month and date.month <= 12) then return ("Wrong month: " .. unwarp(date)) end if not date.day or not (1 <= date.day and date.day <= month_end_day(date.month,date.year)) then return ("Wrong day: " .. unwarp(date)) end local timedate = os.time{year=date.year, month=date.month, day=date.day} local date = os.date("%Y-%m-%d", timedate) return date end -- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"12 декабря 2020"}}) -- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"1.2.1602"}}) -- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"декабрь 2020"}}) -- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"12-2020"}}) -- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"12.12.2021"}}) -- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"2021.12.12"}}) -- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"2021.11"}}) -- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"11.2021"}}) function p.BoxDate( frame ) local args = getArgs(frame, { frameOnly = true }) local txtDateIn, strFormat = args[1], args[2] local txtDateOut, date, status = p.bxDate(txtDateIn, strFormat, params) if status.brk then return error(status.errorText) else return txtDateOut end end function p.bxDate( txtDateIn , strFormat, params ) -- к отладке local txtDateOut, date, status = "", {}, {brk = false, errorCat = "", errorText = ""} strFormat = strFormat or "j xg Y" -- заглушка - таблица параметров на будущее params = params or {} if not txtDateIn then status.errorText = e.no_data status.errorCat = category.no_parameters status.brk = true else -- заполнение служебных таблиц filling_months(mnlang, month_lang) end if not status.brk then -- парсинг входящей даты по шаблону date = parse_date(txtDateIn) -- заменить сообщения об ошибках на списочные if not (date.year and type(date.year) == 'number') then status.errorText = string.format(e.box_date,txtDateIn) status.errorCat = category.incomplete_parameters status.brk = true end if not inbord(date.month,1,12) then status.errorText = string.format(e.box_date,txtDateIn) status.errorCat = category.incomplete_parameters status.brk = true end if not date.day and string.find(strFormat,"[dDjlNwzW]") then strFormat = trim(string.gsub(string.gsub(strFormat,"xg","F"),"[dDjlNwzW]","")) elseif not date.day then elseif not inbord(date.day,1,month_end_day(date.month,date.year)) then status.errorText = string.format(e.box_date,txtDateIn) status.errorCat = category.incomplete_parameters status.brk = true end end if not status.brk then txtDateOut = mwlang:formatDate(strFormat,tCon({date.year,date.month,date.day},"-"),true) end return txtDateOut, date, status end function p.ToDate( frame ) -- возможно неиспользуемая local args = getArgs(frame, { frameOnly = true }) local mwlang = mw.getContentLanguage() local datein = args[1] local format = "j xg Y" if not string.match(datein, "%p") then return datein elseif not args[2] then else format = args[2] end return mwlang:formatDate(format,datein,true) end -- =p.unitime(mw.getCurrentFrame():newChild{title="smth",args={"−1:30","1"}}) function p.unitime( frame ) local args = getArgs(frame, { frameOnly = true }) local DST = 0 if not args[2] then else DST = 1 end local utcin = "" local input = args[1] if not input then return "" end if inlist(input:upper(),tzs_names) then utcin = known_tzs[input:upper()] elseif (string.sub(input:upper(),1,3) == 'UTC') and (string.len(input) < 10) then utcin = string.sub(input,4) else if string.sub(input,1,1) == '[' or string.sub(input,1,1) == '{' or string.sub(input,1,1):upper() == 'U' or string.sub(input,1,1):upper() == 'M' then return input -- elseif not string.find(string.upper(string.sub(input,1,1)),"[\65-\90]") or -- not string.find(string.upper(string.sub(input,1,1)),"[\192-\223]") then -- return input else utcin = input end end -- elseif string.sub(input,1,3) ~= "−" then utcin = input -- or not (not input:find("[А-я]")) при наличии в строке юникода не работает local output = "" if DST == 0 then output = utc(utcin) else output = utc(utcin) .. ", [[летнее время|летом]] " .. utc(utcin,DST) end return output end -- УСТАРЕЛО -- =p.OldDate(mw.getCurrentFrame():newChild{title="smth",args={"20.02.2020","ю",["bc"]="1",["wd"]="1",["wy"]="1",["sq_brts"]="1",["yearmark"]="г."}}) function p.OldDate( frame ) local args = getArgs(frame, { frameOnly = true }) if not args[1] then return err end local gdate, jdate = {}, {} local strin = args[1] local cal = args[2]:lower() or "г" local bc = is(args["bc"]) local wd = is(args["wd"]) local wm = is(args["wm"]) local wy = is(args["wy"]) if not wd then wm = false end local sq_brts = is(args["sq_brts"]) local yearmark = "года" if yesno(args["yearmark"]) then elseif yesno(args["yearmark"]) == false then yearmark = "" else yearmark = trim(args["yearmark"]) or "года" end -- local infocard = is(args["infocard"]) -- local catName = args["catName"] or false local datein = numstr2date(strin) datein.year = astroyear(datein.year, bc) jdate, gdate = recalc(datein,cal) return double_couple(jdate, gdate, wd, wm, wy, sq_brts, yearmark) end -- =p.NewDate(mw.getCurrentFrame():newChild{title="Salt",args={"2020-02-20"}}) -- =p.NewDate(mw.getCurrentFrame():newChild{title="smth",args={"20.02.2020","ю",["bc"]="1",["wd"]="1",["wy"]="1",["sq_brts"]="1",["yearmark"]="г."}}) -- =p.NewDate(mw.getCurrentFrame():newChild{title="smth",args={"20.02.2020",["bc"]="0",["wd"]="1",["wy"]="1",["sq_brts"]="0",["yearmark"]=""}}) function p.NewDate( frame ) local args = getArgs(frame, { frameOnly = true }) if not args[1] then return err end local strin = args[1] local year, month, day if not not strin:match( "(-?%d%d%d%d%d)-(%d%d)-(%d%d)" ) then year, month, day = strin:match( "(-?%d%d%d%d%d)-(%d%d)-(%d%d)" ) elseif not not strin:match( "(-?%d+)-(%d+)-(%d+)" ) then year, month, day = strin:match( "(-?%d+)-(%d+)-(%d+)" ) elseif not not strin:match( "(%d%d)%.(%d%d)%.(-?%d%d%d%d%d)" ) then day, month, year = strin:match( "(%d%d)%.(%d%d)%.(-?%d%d%d%d%d)" ) elseif not not strin:match( "(%d+)%.(%d+)%.(-?%d+)" ) then day, month, year = strin:match( "(%d+)%.(%d+)%.(-?%d+)" ) end if not year then return error(args[1] .. " не подходит под форматы yyyy-mm-dd или dd.mm.yyyy") end local cal = "г" if (not args[2]) or (args[2] == "") then cal = "г" else cal = args[2]:lower() end local bc,wd,wm,wy,sq_brts = is(args["bc"]), is(args["wd"]), is(args["wd"]) and is(args["wm"]), is(args["wy"]), is(args["sq_brts"]) year = astroyear(purif(year),bc) local datein = {["year"]=purif(year), ["month"]=purif(month), ["day"]=purif(day)} local jdate, gdate = recalc(datein,cal) local yearmark = "года" local ym = args["yearmark"] or "" if yesno(ym) then elseif yesno(ym) == false then yearmark = "" else if not not ym:match("(%d+)") then error("Цифры в обозначении года: " .. ym) else yearmark = trim(ym) or "года" end end return double_couple(jdate, gdate, wd, wm, wy, sq_brts, yearmark) end -- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={}}) -- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"3","июня",nil,"21","мая"}}) -- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"28 августа","","1916 года","15"}}) -- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"3","июня","1900","21","мая"}}) -- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"6","июня","1889 год","25","мая"}}) -- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"28","ноября","1917","15"}}) -- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"28 августа","nil","1916 года","15"}}) -- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"4","января","1915","22","декабря","1914 года"}}) -- {{OldStyleDate|день (НС)|месяц (НС)|год (НС)|день (СС)|месяц (СС)|год (СС)}} function p.Test( frame ) local args = getArgs(frame, { frameOnly = true }) -- необходима проверка и замена nil на " " --[[mw.log((args[1] or "") .. " " .. (args[2] or "") .. " " .. (args[3] or "") .. " " .. (args[4] or "") .. " " .. (args[5] or "") .. " " .. (args[6] or "")) ]]-- local ingdate = triple_txt2date(args[1],args[2],args[3]) local injdate = triple_txt2date(args[4],args[5],args[6]) local j1date, g1date, j2date, g2date = init(4) mw.log("ingdate-".. (undate(ingdate) or "")) mw.log("injdate-".. (undate(injdate) or "")) local bc,wd,wm,wy,sq_brts,ny = is(args["bc"]), is(args["wd"]), is(args["wd"]) and is(args["wm"]), is(args["wy"]), is(args["sq_brts"]), is(args["ny"]) -- подавление формата для локальных тестов local wd, wm, wy = true, true, true local yearmark = "года" local ym = args["yearmark"] or ((mw.ustring.match((args[3] or ""),"(%a+)") or mw.ustring.match((args[6] or ""),"(%a+)")) or "") -- mw.log("ym " .. ym) if yesno(ym) then elseif yesno(ym) == false then yearmark = "" else if not not ym:match("(%d+)") then error("Цифры в обозначении года: " .. ym) else yearmark = trim(ym) or "года" end end if isdate(ingdate) or isdate(injdate) then if isdate(ingdate) then j1date, g1date = recalc(ingdate,"g") ingdate["full"] = true end if isdate(injdate) then j2date, g2date = recalc(injdate,"j") injdate["full"] = true end if ispartdate(ingdate) and ispartdate(injdate) then mw.log("📏 " .. dmdist(ingdate,injdate)) mw.log("📏 " .. dmdist(j1date,g1date)) mw.log("📏 " .. dmdist(j2date,g2date)) mw.log("📏 " .. dmdist(ingdate,g1date)) mw.log("📏 " .. dmdist(injdate,j2date)) end end if ny then if isyear(j1date) then else j1date["year"] = "" end if isyear(j2date) == nil then else j2date["year"] = "" end if isyear(g1date) == nil then else g1date["year"] = "" end if isyear(g2date) == nil then else g2date["year"] = "" end end if (isdate(j1date) and isdate(g1date) and isdate(j2date) and isdate(g2date)) then if ((j1date.year == j2date.year) and (j1date.month == j2date.month) and (j1date.day == j2date.day)) then return double_couple(j1date, g1date, wd, wm, wy, sq_brts, yearmark) else mw.log("📏 " .. (tostring(dmdist(ingdate,injdate)) or "")) return glue(args[1],args[2],args[3],args[4],args[5],args[6]) -- категория (предположительная разница в днях) и частичный вывод end elseif isdate(j1date) and isdate(g1date) then return double_couple(j1date, g1date, wd, wm, wy, sq_brts, yearmark) -- категория плюс частичная проверка elseif isdate(j2date) and isdate(g2date) then return double_couple(j2date, g2date, wd, wm, wy, sq_brts, yearmark) -- категория плюс частичная проверка elseif (ispartdate(ingdate) and ispartdate(injdate)) then mw.log("ingdate ".. (undate(ingdate) or "")) mw.log("injdate ".. (undate(injdate) or "")) mw.log("j1date " .. (undate(j1date ) or "")) mw.log("j2date " .. (undate(j2date ) or "")) mw.log("g1date " .. (undate(g1date ) or "")) mw.log("g2date " .. (undate(g2date ) or "")) mw.log("📏 " .. (tostring(partdist(ingdate,injdate)) or "").. " — " .. (tostring(partdist(injdate,ingdate)) or "")) return glue(args[1],args[2],args[3],args[4],args[5],args[6]) -- частичный или полный вывод, категория else mw.log("ingdate ".. (undate(ingdate) or "")) mw.log("injdate ".. (undate(injdate) or "")) mw.log("j1date " .. (undate(j1date ) or "")) mw.log("j2date " .. (undate(j2date ) or "")) mw.log("g1date " .. (undate(g1date ) or "")) mw.log("g2date " .. (undate(g2date ) or "")) return err .. category.incomplete_parameters end end return p a4a91f134ad3e3b246b3a6681a4ae438da766df4 Модуль:Category handler 828 31 614 415 2024-08-16T16:22:38Z DuOfOrl 5 1 версия импортирована Scribunto text/plain -------------------------------------------------------------------------------- -- -- -- CATEGORY HANDLER -- -- -- -- This module implements the {{category handler}} template in Lua, -- -- with a few improvements: all namespaces and all namespace aliases -- -- are supported, and namespace names are detected automatically for -- -- the local wiki. This module requires [[Module:Namespace detect]] -- -- and [[Module:Yesno]] to be available on the local wiki. It can be -- -- configured for different wikis by altering the values in -- -- [[Module:Category handler/config]], and pages can be blacklisted -- -- from categorisation by using [[Module:Category handler/blacklist]]. -- -- -- -------------------------------------------------------------------------------- -- Load required modules local yesno = require('Module:Yesno') -- Lazily load things we don't always need local mShared, mappings local p = {} -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function trimWhitespace(s, removeBlanks) if type(s) ~= 'string' then return s end s = s:match('^%s*(.-)%s*$') if removeBlanks then if s ~= '' then return s else return nil end else return s end end -------------------------------------------------------------------------------- -- CategoryHandler class -------------------------------------------------------------------------------- local CategoryHandler = {} CategoryHandler.__index = CategoryHandler function CategoryHandler.new(data, args) local obj = setmetatable({ _data = data, _args = args }, CategoryHandler) -- Set the title object do local pagename = obj:parameter('demopage') local success, titleObj if pagename then success, titleObj = pcall(mw.title.new, pagename) end if success and titleObj then obj.title = titleObj if titleObj == mw.title.getCurrentTitle() then obj._usesCurrentTitle = true end else obj.title = mw.title.getCurrentTitle() obj._usesCurrentTitle = true end end -- Set suppression parameter values for _, key in ipairs{'nocat', 'categories'} do local value = obj:parameter(key) value = trimWhitespace(value, true) obj['_' .. key] = yesno(value) end do local subpage = obj:parameter('subpage') local category2 = obj:parameter('category2') if type(subpage) == 'string' then subpage = mw.ustring.lower(subpage) end if type(category2) == 'string' then subpage = mw.ustring.lower(category2) end obj._subpage = trimWhitespace(subpage, true) obj._category2 = trimWhitespace(category2) -- don't remove blank values end return obj end function CategoryHandler:parameter(key) local parameterNames = self._data.parameters[key] local pntype = type(parameterNames) if pntype == 'string' or pntype == 'number' then return self._args[parameterNames] elseif pntype == 'table' then for _, name in ipairs(parameterNames) do local value = self._args[name] if value ~= nil then return value end end return nil else error(string.format( 'invalid config key "%s"', tostring(key) ), 2) end end function CategoryHandler:isSuppressedByArguments() return -- See if a category suppression argument has been set. self._nocat == true or self._categories == false or ( self._category2 and self._category2 ~= self._data.category2Yes and self._category2 ~= self._data.category2Negative ) -- Check whether we are on a subpage, and see if categories are -- suppressed based on our subpage status. or self._subpage == self._data.subpageNo and self.title.isSubpage or self._subpage == self._data.subpageOnly and not self.title.isSubpage end function CategoryHandler:shouldSkipBlacklistCheck() -- Check whether the category suppression arguments indicate we -- should skip the blacklist check. return self._nocat == false or self._categories == true or self._category2 == self._data.category2Yes end function CategoryHandler:matchesBlacklist() if self._usesCurrentTitle then return self._data.currentTitleMatchesBlacklist else mShared = mShared or require('Module:Category handler/shared') return mShared.matchesBlacklist( self.title.prefixedText, mw.loadData('Module:Category handler/blacklist') ) end end function CategoryHandler:isSuppressed() -- Find if categories are suppressed by either the arguments or by -- matching the blacklist. return self:isSuppressedByArguments() or not self:shouldSkipBlacklistCheck() and self:matchesBlacklist() end function CategoryHandler:getNamespaceParameters() if self._usesCurrentTitle then return self._data.currentTitleNamespaceParameters else if not mappings then mShared = mShared or require('Module:Category handler/shared') mappings = mShared.getParamMappings(true) -- gets mappings with mw.loadData end return mShared.getNamespaceParameters( self.title, mappings ) end end function CategoryHandler:namespaceParametersExist() -- Find whether any namespace parameters have been specified. -- We use the order "all" --> namespace params --> "other" as this is what -- the old template did. if self:parameter('all') then return true end if not mappings then mShared = mShared or require('Module:Category handler/shared') mappings = mShared.getParamMappings(true) -- gets mappings with mw.loadData end for ns, params in pairs(mappings) do for i, param in ipairs(params) do if self._args[param] then return true end end end if self:parameter('other') then return true end return false end function CategoryHandler:getCategories() local params = self:getNamespaceParameters() local nsCategory for i, param in ipairs(params) do local value = self._args[param] if value ~= nil then nsCategory = value break end end if nsCategory ~= nil or self:namespaceParametersExist() then -- Namespace parameters exist - advanced usage. if nsCategory == nil then nsCategory = self:parameter('other') end local ret = {self:parameter('all')} local numParam = tonumber(nsCategory) if numParam and numParam >= 1 and math.floor(numParam) == numParam then -- nsCategory is an integer ret[#ret + 1] = self._args[numParam] else ret[#ret + 1] = nsCategory end if #ret < 1 then return nil else return table.concat(ret) end elseif self._data.defaultNamespaces[self.title.namespace] then -- Namespace parameters don't exist, simple usage. return self._args[1] end return nil end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p = {} function p._exportClasses() -- Used for testing purposes. return { CategoryHandler = CategoryHandler } end function p._main(args, data) data = data or mw.loadData('Module:Category handler/data') local handler = CategoryHandler.new(data, args) if handler:isSuppressed() then return nil end return handler:getCategories() end function p.main(frame, data) data = data or mw.loadData('Module:Category handler/data') local args = require('Module:Arguments').getArgs(frame, { wrappers = data.wrappers, valueFunc = function (k, v) v = trimWhitespace(v) if type(k) == 'number' then if v ~= '' then return v else return nil end else return v end end }) return p._main(args, data) end return p b74dd63857b24904ac452429b11213f18647471f Модуль:Category handler/blacklist 828 75 616 123 2024-08-16T16:22:38Z DuOfOrl 5 1 версия импортирована Scribunto text/plain -- This module contains the blacklist used by [[Module:Category handler]]. -- Pages that match Lua patterns in this list will not be categorised unless -- categorisation is explicitly requested. return { '^Main Page$', -- don't categorise the main page. -- Don't categorise the following pages or their subpages. -- "%f[/\0]" matches if the next character is "/" or the end of the string. '^Wikipedia:Cascade%-protected items%f[/\0]', '^User:UBX%f[/\0]', -- The userbox "template" space. '^User talk:UBX%f[/\0]', -- Don't categorise subpages of these pages, but allow -- categorisation of the base page. '^Wikipedia:Template messages/.*$', '/[aA]rchive' -- Don't categorise archives. } c84948ad9808d5d323408d5d10d5652f748a0550 Модуль:Category handler/config 828 70 618 113 2024-08-16T16:22:39Z DuOfOrl 5 1 версия импортирована Scribunto text/plain -------------------------------------------------------------------------------- -- [[Module:Category handler]] configuration data -- -- Language-specific parameter names and values can be set here. -- -- For blacklist config, see [[Module:Category handler/blacklist]]. -- -------------------------------------------------------------------------------- local cfg = {} -- Don't edit this line. -------------------------------------------------------------------------------- -- Start configuration data -- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Parameter names -- -- These configuration items specify custom parameter names. -- -- To add one extra name, you can use this format: -- -- -- -- foo = 'parameter name', -- -- -- -- To add multiple names, you can use this format: -- -- -- -- foo = {'parameter name 1', 'parameter name 2', 'parameter name 3'}, -- -------------------------------------------------------------------------------- cfg.parameters = { -- The nocat and categories parameter suppress -- categorisation. They are used with Module:Yesno, and work as follows: -- -- cfg.nocat: -- Result of yesno() Effect -- true Categorisation is suppressed -- false Categorisation is allowed, and -- the blacklist check is skipped -- nil Categorisation is allowed -- -- cfg.categories: -- Result of yesno() Effect -- true Categorisation is allowed, and -- the blacklist check is skipped -- false Categorisation is suppressed -- nil Categorisation is allowed nocat = 'nocat', categories = 'categories', -- The parameter name for the legacy "category2" parameter. This skips the -- blacklist if set to the cfg.category2Yes value, and suppresses -- categorisation if present but equal to anything other than -- cfg.category2Yes or cfg.category2Negative. category2 = 'category2', -- cfg.subpage is the parameter name to specify how to behave on subpages. subpage = 'subpage', -- The parameter for data to return in all namespaces. all = 'all', -- The parameter name for data to return if no data is specified for the -- namespace that is detected. other = 'other', -- The parameter name used to specify a page other than the current page; -- used for testing and demonstration. demopage = 'page', } -------------------------------------------------------------------------------- -- Parameter values -- -- These are set values that can be used with certain parameters. Only one -- -- value can be specified, like this: -- -- -- -- cfg.foo = 'value name' -- -- -------------------------------------------------------------------------------- -- The following settings are used with the cfg.category2 parameter. Setting -- cfg.category2 to cfg.category2Yes skips the blacklist, and if cfg.category2 -- is present but equal to anything other than cfg.category2Yes or -- cfg.category2Negative then it supresses cateogrisation. cfg.category2Yes = 'yes' cfg.category2Negative = '¬' -- The following settings are used with the cfg.subpage parameter. -- cfg.subpageNo is the value to specify to not categorise on subpages; -- cfg.subpageOnly is the value to specify to only categorise on subpages. cfg.subpageNo = 'no' cfg.subpageOnly = 'only' -------------------------------------------------------------------------------- -- Default namespaces -- -- This is a table of namespaces to categorise by default. The keys are the -- -- namespace numbers. -- -------------------------------------------------------------------------------- cfg.defaultNamespaces = { [ 0] = true, -- main [ 6] = true, -- file [ 12] = true, -- help [ 14] = true, -- category [100] = true, -- portal [108] = true, -- book } -------------------------------------------------------------------------------- -- Wrappers -- -- This is a wrapper template or a list of wrapper templates to be passed to -- -- [[Module:Arguments]]. -- -------------------------------------------------------------------------------- cfg.wrappers = 'Template:Category handler' -------------------------------------------------------------------------------- -- End configuration data -- -------------------------------------------------------------------------------- return cfg -- Don't edit this line. 373cd107b13a5b00e6a1b7e66a749f12502c849d Модуль:Category handler/data 828 69 620 111 2024-08-16T16:22:39Z DuOfOrl 5 1 версия импортирована Scribunto text/plain -- This module assembles data to be passed to [[Module:Category handler]] using -- mw.loadData. This includes the configuration data and whether the current -- page matches the title blacklist. local data = require('Module:Category handler/config') local mShared = require('Module:Category handler/shared') local blacklist = require('Module:Category handler/blacklist') local title = mw.title.getCurrentTitle() data.currentTitleMatchesBlacklist = mShared.matchesBlacklist( title.prefixedText, blacklist ) data.currentTitleNamespaceParameters = mShared.getNamespaceParameters( title, mShared.getParamMappings() ) return data abbc68048ff698e88dda06b64ecf384bbf583120 Модуль:Category handler/shared 828 74 622 121 2024-08-16T16:22:39Z DuOfOrl 5 1 версия импортирована Scribunto text/plain -- This module contains shared functions used by [[Module:Category handler]] -- and its submodules. local p = {} function p.matchesBlacklist(page, blacklist) for i, pattern in ipairs(blacklist) do local match = mw.ustring.match(page, pattern) if match then return true end end return false end function p.getParamMappings(useLoadData) local dataPage = 'Module:Namespace detect/data' if useLoadData then return mw.loadData(dataPage).mappings else return require(dataPage).mappings end end function p.getNamespaceParameters(titleObj, mappings) -- We don't use title.nsText for the namespace name because it adds -- underscores. local mappingsKey if titleObj.isTalkPage then mappingsKey = 'talk' else mappingsKey = mw.site.namespaces[titleObj.namespace].name end mappingsKey = mw.ustring.lower(mappingsKey) return mappings[mappingsKey] or {} end return p d2d5de1a031e6ce97c242cbfa8afe7a92cb9eca5 Модуль:Message box 828 21 624 137 2024-08-16T16:22:40Z DuOfOrl 5 1 версия импортирована Scribunto text/plain -- This is a meta-module for producing message box templates, including -- {{mbox}}, {{ambox}}, {{imbox}}, {{tmbox}}, {{ombox}}, {{cmbox}} and {{fmbox}}. -- Load necessary modules. require('strict') local getArgs local categoryHandler = require('Module:Category handler')._main local yesno = require('Module:Yesno') local boxDate = require('Module:Calendar').bxDate; -- Get a language object for formatDate and ucfirst. local lang = mw.language.getContentLanguage() -- Define constants local CONFIG_MODULE = 'Module:Message box/configuration' -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function getTitleObject(...) -- Get the title object, passing the function through pcall -- in case we are over the expensive function count limit. local success, title = pcall(mw.title.new, ...) if success then return title end end local function union(t1, t2) -- Returns the union of two arrays. local vals = {} for i, v in ipairs(t1) do vals[v] = true end for i, v in ipairs(t2) do vals[v] = true end local ret = {} for k in pairs(vals) do table.insert(ret, k) end table.sort(ret) return ret end local function getArgNums(args, prefix) local nums = {} for k, v in pairs(args) do local num = mw.ustring.match(tostring(k), '^' .. prefix .. '([1-9]%d*)$') if num then table.insert(nums, tonumber(num)) end end table.sort(nums) return nums end -- локальная обёртка, игнорирует таблицу с номерами дня, месяца и года local function formatDate(txtDateIn, strFormat, params) local txtDateOut, date, status = boxDate(txtDateIn, strFormat, params) if status.brk then return error(status.errorText) else return txtDateOut end end -------------------------------------------------------------------------------- -- Box class definition -------------------------------------------------------------------------------- local MessageBox = {} MessageBox.__index = MessageBox function MessageBox.new(boxType, args, cfg) args = args or {} local obj = {} -- Set the title object and the namespace. obj.title = getTitleObject(args.page) or mw.title.getCurrentTitle() -- Set the config for our box type. obj.cfg = cfg[boxType] if not obj.cfg then local ns = obj.title.namespace -- boxType is "mbox" or invalid input if ns == 0 then obj.cfg = cfg.ambox -- main namespace elseif ns == 6 then obj.cfg = cfg.imbox -- file namespace elseif ns == 14 then obj.cfg = cfg.cmbox -- category namespace else local nsTable = mw.site.namespaces[ns] if nsTable and nsTable.isTalk then obj.cfg = cfg.tmbox -- any talk namespace else obj.cfg = cfg.ombox -- other namespaces or invalid input end end end -- Set the arguments, and remove all blank arguments except for the ones -- listed in cfg.allowBlankParams. do local newArgs = {} for k, v in pairs(args) do if v ~= '' then newArgs[k] = v end end for i, param in ipairs(obj.cfg.allowBlankParams or {}) do newArgs[param] = args[param] end obj.args = newArgs end -- Define internal data structure. obj.categories = {} obj.classes = {} return setmetatable(obj, MessageBox) end function MessageBox:addCat(ns, cat, sort) if not cat then return nil end if sort then cat = string.format('[[Категория:%s|%s]]', cat, sort) else cat = string.format('[[Категория:%s]]', cat) end self.categories[ns] = self.categories[ns] or {} table.insert(self.categories[ns], cat) end function MessageBox:addClass(class) if not class then return nil end table.insert(self.classes, class) end function MessageBox:setParameters() local args = self.args local cfg = self.cfg -- Get type data. self.type = args.type local typeData = cfg.types[self.type] self.invalidTypeError = cfg.showInvalidTypeError and self.type and not typeData typeData = typeData or cfg.types[cfg.default] self.typeClass = typeData.class self.typeImage = typeData.image -- Find if the box has been wrongly substituted. self.isSubstituted = cfg.substCheck and args.subst == 'SUBST' -- Find whether we are using a small message box. self.isSmall = cfg.allowSmall and ( cfg.smallParam and args.small == cfg.smallParam or not cfg.smallParam and yesno(args.small) ) -- Add attributes, classes and styles. self.id = args.id self.name = args.name if self.name then self:addClass('mbox-' .. string.gsub(self.name,' ','_')) end if yesno(args.plainlinks) ~= false then self:addClass('plainlinks') end for _, class in ipairs(cfg.classes or {}) do self:addClass(class) end if self.isSmall then self:addClass(cfg.smallClass or 'mbox-small') end self:addClass(self.typeClass) self:addClass(args.class) self.style = args.style self.attrs = args.attrs self.dataLabel1 = args['data-label-1'] self.dataLabel2 = args['data-label-2'] self.dataLabel3 = args['data-label-3'] self.dataValue1 = args['data-value-1'] self.dataValue2 = args['data-value-2'] self.dataValue3 = args['data-value-3'] -- Set text style. self.textstyle = args.textstyle -- Find if we are on the template page or not. This functionality is only -- used if useCollapsibleTextFields is set, or if both cfg.templateCategory -- and cfg.templateCategoryRequireName are set. self.useCollapsibleTextFields = cfg.useCollapsibleTextFields if self.useCollapsibleTextFields or cfg.templateCategory and cfg.templateCategoryRequireName then self.name = args.name if self.name then local templateName = mw.ustring.match( self.name, '^[tT][eE][mM][pP][lL][aA][tT][eE][%s_]*:[%s_]*(.*)$' ) or self.name templateName = ('Template:' .. templateName) or ('Шаблон:' .. templateName) self.templateTitle = getTitleObject(templateName) end self.isTemplatePage = self.templateTitle and mw.title.equals(self.title, self.templateTitle) end -- Process data for collapsible text fields. At the moment these are only -- used in {{ambox}}. if self.useCollapsibleTextFields then -- Get the self.issue value. if self.isSmall and args.smalltext then self.issue = args.smalltext else if args.sect and args.sect ~= '' or nil then local issue_sect = args.issue_sect issue_sect = type(issue_sect) == 'string' and issue_sect ~= '' and issue_sect or nil local text_sect = args.text_sect text_sect = type(text_sect) == 'string' and text_sect ~= '' and text_sect or nil local issues = {} table.insert(issues, issue_sect) table.insert(issues, text_sect) self.issue = table.concat(issues, ' ') else local issue = args.issue issue = type(issue) == 'string' and issue ~= '' and issue or nil local text = args.text text = type(text) == 'string' and text or nil local issues = {} table.insert(issues, issue) table.insert(issues, text) self.issue = table.concat(issues, ' ') end end -- Get the self.talk value. local talk = args.talk -- Show talk links on the template page or template subpages if the talk -- parameter is blank. if talk == '' and self.templateTitle and ( mw.title.equals(self.templateTitle, self.title) or self.title:isSubpageOf(self.templateTitle) ) then talk = '#' elseif talk == '' then talk = nil end if talk then -- If the talk value is a talk page, make a link to that page. Else -- assume that it's a section heading, and make a link to the talk -- page of the current page with that section heading. local talkTitle = getTitleObject(talk) local talkArgIsTalkPage = true if not talkTitle or not talkTitle.isTalkPage then talkArgIsTalkPage = false talkTitle = getTitleObject( self.title.text, mw.site.namespaces[self.title.namespace].talk.id ) end if talkTitle and talkTitle.exists then local talkText = 'Соответствующую дискуссию можно найти на' if talkArgIsTalkPage then talkText = string.format( '%s [[%s|%s]].', talkText, talk, talkTitle.prefixedText ) else talkText = string.format( '%s [[%s#%s|странице обсуждения]].', talkText, talkTitle.prefixedText, talk ) end self.talk = talkText end end -- Get other values. self.fix = args.fix ~= '' and args.fix or nil local date if args.date and args.date ~= '' then local status, result = pcall(formatDate, args.date) if status then date = string.format("(<span class='date'>%s</span>)", result) else date = string.format("<span class='error'>(Строка «%s» не является верной датой, пожалуйста, укажите дату в формате <code>ГГГГ-ММ-ДД</code>)</span>", args.date) end elseif args.date == '' and self.isTemplatePage then date = string.format("(<span class='date'>%s</span>)", formatDate( lang:formatDate('Y-m-d') ) ) -- тут возникновения ошибки, связанной с пользовательским вводом, не будет end if date then self.date = string.format(" <span class='mbox-date'>''%s''</span>", date) end self.info = args.info if yesno(args.removalnotice) then self.removalNotice = cfg.removalNotice end if args.shortFix then self.shortFix = args.shortFix end end -- Set the non-collapsible text field. At the moment this is used by all box -- types other than ambox, and also by ambox when small=yes. if self.isSmall then self.text = args.smalltext or args.text else self.text = args.text self.textsmall = args['text-small'] end -- Set the below row. self.below = cfg.below and args.below -- General image settings. self.imageCellDiv = not self.isSmall and cfg.imageCellDiv self.imageEmptyCell = cfg.imageEmptyCell if cfg.imageEmptyCellStyle then self.imageEmptyCellStyle = 'border:none;padding:0px;width:1px' end -- Left image settings. local imageLeft = self.isSmall and args.smallimage or args.image if cfg.imageCheckBlank and imageLeft ~= 'blank' and imageLeft ~= 'none' and imageLeft ~= '' or not cfg.imageCheckBlank and imageLeft ~= 'none' then self.imageLeft = imageLeft if not imageLeft then local imageSize = self.isSmall and (cfg.imageSmallSize or '30x30px') or cfg.imageSize or '40x40px' self.imageLeft = string.format('[[File:%s|%s|alt=]]', self.typeImage or 'Information icon4.svg', imageSize) end end -- Right image settings. local imageRight = self.isSmall and args.smallimageright or args.imageright if not (cfg.imageRightNone and imageRight == 'none') then self.imageRight = imageRight end -- set templatestyles self.base_templatestyles = cfg.templatestyles end function MessageBox:setMainspaceCategories() local args = self.args local cfg = self.cfg local date = nil if not cfg.allowMainspaceCategories then return nil end local nums = {} for _, prefix in ipairs{'cat', 'category', 'all'} do args[prefix .. '1'] = args[prefix] nums = union(nums, getArgNums(args, prefix)) end -- The following is roughly equivalent to the old {{Ambox/category}}. local status, result = pcall(formatDate, args.date, 'xg Y') if status then date = result end date = type(date) == 'string' and date local preposition = 'с' local suffix = 'года' for _, num in ipairs(nums) do local mainCat = args['cat' .. tostring(num)] or args['category' .. tostring(num)] local allCat = args['all' .. tostring(num)] mainCat = type(mainCat) == 'string' and mainCat allCat = type(allCat) == 'string' and allCat if mainCat and date and date ~= '' then local catTitle = string.format('%s %s %s %s', mainCat, preposition, date, suffix) self:addCat(0, catTitle) catTitle = getTitleObject('Категория:' .. catTitle) local status, result = pcall(formatDate, args.date) if not status then self:addCat(0, 'Википедия:Статьи с недопустимым параметром даты в шаблоне-сообщении') end elseif mainCat and (not date or date == '') then self:addCat(0, mainCat) end if allCat then self:addCat(0, allCat) end end end function MessageBox:setTemplateCategories() local args = self.args local cfg = self.cfg -- Add template categories. if cfg.templateCategory then if cfg.templateCategoryRequireName then if self.isTemplatePage then self:addCat(10, cfg.templateCategory) end elseif not self.title.isSubpage then self:addCat(10, cfg.templateCategory) end end -- Add template error categories. if cfg.templateErrorCategory then local templateErrorCategory = cfg.templateErrorCategory local templateCat, templateSort if not self.name and not self.title.isSubpage then templateCat = templateErrorCategory elseif self.isTemplatePage then local paramsToCheck = cfg.templateErrorParamsToCheck or {} local count = 0 for i, param in ipairs(paramsToCheck) do if not args[param] then count = count + 1 end end if count > 0 then templateCat = templateErrorCategory templateSort = tostring(count) end if self.categoryNums and #self.categoryNums > 0 then templateCat = templateErrorCategory templateSort = 'C' end end self:addCat(10, templateCat, templateSort) end end function MessageBox:setAllNamespaceCategories() -- Set categories for all namespaces. if self.invalidTypeError then local allSort = (self.title.namespace == 0 and 'Main:' or '') .. self.title.prefixedText self:addCat('all', 'Википедия:Необходимо исправить параметр в шаблоне-сообщении', allSort) end if self.isSubstituted then self:addCat('all', 'Википедия:Страницы с ошибочно подставленными шаблонами') end if self.isSmall then self:addCat(0, 'Википедия:Страницы с малыми шаблонами-сообщениями') end end function MessageBox:setCategories() if self.title.namespace == 0 then self:setMainspaceCategories() elseif self.title.namespace == 10 then self:setTemplateCategories() end self:setAllNamespaceCategories() end function MessageBox:renderCategories() -- Convert category tables to strings and pass them through -- [[Module:Category handler]]. return categoryHandler{ main = table.concat(self.categories[0] or {}), template = table.concat(self.categories[10] or {}), all = table.concat(self.categories.all or {}), nocat = self.args.nocat, page = self.args.page } end function MessageBox:export() local root = mw.html.create() -- Add the subst check error. if self.isSubstituted and self.name then root:tag('b') :addClass('error') :wikitext(string.format( 'Шаблон <code>%s[[Шаблон:%s|%s]]%s</code> был неккоректно подставлен.', mw.text.nowiki('{{'), self.name, self.name, mw.text.nowiki('}}') )) end -- Conditional TemplateStyles loading if self.base_templatestyles then local frame = mw.getCurrentFrame() root:wikitext(frame:extensionTag{ name = 'templatestyles', args = { src = self.base_templatestyles }, }) end -- Create the box table. local boxTable = root:tag('table') boxTable:attr('id', self.id or nil) for i, class in ipairs(self.classes or {}) do boxTable:addClass(class or nil) end boxTable :cssText(self.style or nil) :attr('role', 'presentation') if self.dataLabel1 then boxTable:attr('data-' .. self.dataLabel1, self.dataValue1) end if self.dataLabel2 then boxTable:attr('data-' .. self.dataLabel2, self.dataValue2) end if self.dataLabel3 then boxTable:attr('data-' .. self.dataLabel3, self.dataValue3) end if self.attrs then boxTable:attr(self.attrs) end -- Add the left-hand image. local row = boxTable:tag('tr') if self.imageLeft then local imageLeftCell = row:tag('td'):addClass('mbox-image') if self.imageCellDiv then -- If we are using a div, redefine imageLeftCell so that the image -- is inside it. Divs use style="width: 52px;", which limits the -- image width to 52px. If any images in a div are wider than that, -- they may overlap with the text or cause other display problems. imageLeftCell = imageLeftCell:tag('div'):css('width', '52px') end imageLeftCell:wikitext(self.imageLeft or nil) elseif self.imageEmptyCell then -- Some message boxes define an empty cell if no image is specified, and -- some don't. The old template code in templates where empty cells are -- specified gives the following hint: "No image. Cell with some width -- or padding necessary for text cell to have 100% width." row:tag('td') :addClass('mbox-empty-cell') :cssText(self.imageEmptyCellStyle or nil) end -- Add the text. local textCell = row:tag('td'):addClass('mbox-text') if self.useCollapsibleTextFields then -- The message box uses advanced text parameters that allow things to be -- collapsible. At the moment, only ambox uses this. textCell:cssText(self.textstyle or nil) local textCellDiv = textCell:tag('div') textCellDiv :addClass('mbox-text-div') :wikitext(self.issue or nil) local textsmallCellDiv = textCell:tag('div') textsmallCellDiv :addClass('mbox-textsmall-div hide-when-compact') :cssText(self.textsmallstyle) :wikitext(self.textsmall or nil) if (self.talk or self.fix) and not self.isSmall then textsmallCellDiv:tag('span') :addClass('hide-when-compact') :wikitext(self.fix and (' ' .. self.fix) or nil) :wikitext(self.talk and (' ' .. self.talk) or nil) end if self.textsmall or self.fix or self.talk then textsmallCellDiv:wikitext(self.date and (' ' .. self.date) or nil) else textCellDiv:wikitext(self.date and (' ' .. self.date) or nil) end if self.info and not self.isSmall then textsmallCellDiv :tag('span') :addClass('hide-when-compact') :wikitext(self.info and (' ' .. self.info) or nil) end if self.removalNotice then textsmallCellDiv:tag('small') :addClass('hide-when-compact') :tag('i') :wikitext(string.format(" (%s)", self.removalNotice)) end if self.shortFix then textCell:tag('div') :addClass('mbox-multiply') :tag('span') :wikitext(string.format("%s", self.shortFix)) :tag('span') :wikitext(self.date and (' ' .. self.date) or nil) end else -- Default text formatting - anything goes. textCell :cssText(self.textstyle or nil) :wikitext(self.text or nil) end -- Add the right-hand image. if self.imageRight then local imageRightCell = row:tag('td'):addClass('mbox-imageright') if self.imageCellDiv then -- If we are using a div, redefine imageRightCell so that the image -- is inside it. imageRightCell = imageRightCell:tag('div'):css('width', '52px') end imageRightCell :wikitext(self.imageRight or nil) end -- Add the below row. if self.below then boxTable:tag('tr') :tag('td') :attr('colspan', self.imageRight and '3' or '2') :addClass('mbox-text') :cssText(self.textstyle or nil) :wikitext(self.below or nil) end -- Add error message for invalid type parameters. if self.invalidTypeError then root:tag('div') :css('text-align', 'center') :wikitext(string.format( 'Этот шаблон-сообщение использует неверный параметр "type=%s", необходимо исправить.', self.type or '' )) end -- Add categories. root:wikitext(self:renderCategories() or nil) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p, mt = {}, {} function p._exportClasses() -- For testing. return { MessageBox = MessageBox } end function p.main(boxType, args, cfgTables) local box = MessageBox.new(boxType, args, cfgTables or mw.loadData(CONFIG_MODULE)) box:setParameters() box:setCategories() return box:export() end function mt.__index(t, k) return function (frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end return t.main(k, getArgs(frame, {trim = false, removeBlanks = false})) end end return setmetatable(p, mt) f2539b657a9cdadde7c0dd5ad270d3095b2bdd54 660 624 2024-08-16T16:41:09Z DuOfOrl 5 Scribunto text/plain -- This is a meta-module for producing message box templates, including -- {{mbox}}, {{ambox}}, {{imbox}}, {{tmbox}}, {{ombox}}, {{cmbox}} and {{fmbox}}. -- Load necessary modules. require('Module:No globals') local getArgs local categoryHandler = require('Module:Category handler')._main local yesno = require('Module:Yesno') local boxDate = require('Module:Calendar').bxDate; -- Get a language object for formatDate and ucfirst. local lang = mw.language.getContentLanguage() -- Define constants local CONFIG_MODULE = 'Module:Message box/configuration' -------------------------------------------------------------------------------- -- Helper functions -------------------------------------------------------------------------------- local function getTitleObject(...) -- Get the title object, passing the function through pcall -- in case we are over the expensive function count limit. local success, title = pcall(mw.title.new, ...) if success then return title end end local function union(t1, t2) -- Returns the union of two arrays. local vals = {} for i, v in ipairs(t1) do vals[v] = true end for i, v in ipairs(t2) do vals[v] = true end local ret = {} for k in pairs(vals) do table.insert(ret, k) end table.sort(ret) return ret end local function getArgNums(args, prefix) local nums = {} for k, v in pairs(args) do local num = mw.ustring.match(tostring(k), '^' .. prefix .. '([1-9]%d*)$') if num then table.insert(nums, tonumber(num)) end end table.sort(nums) return nums end -- локальная обёртка, игнорирует таблицу с номерами дня, месяца и года local function formatDate(txtDateIn, strFormat, params) local txtDateOut, date, status = boxDate(txtDateIn, strFormat, params) if status.brk then return error(status.errorText) else return txtDateOut end end -------------------------------------------------------------------------------- -- Box class definition -------------------------------------------------------------------------------- local MessageBox = {} MessageBox.__index = MessageBox function MessageBox.new(boxType, args, cfg) args = args or {} local obj = {} -- Set the title object and the namespace. obj.title = getTitleObject(args.page) or mw.title.getCurrentTitle() -- Set the config for our box type. obj.cfg = cfg[boxType] if not obj.cfg then local ns = obj.title.namespace -- boxType is "mbox" or invalid input if ns == 0 then obj.cfg = cfg.ambox -- main namespace elseif ns == 6 then obj.cfg = cfg.imbox -- file namespace elseif ns == 14 then obj.cfg = cfg.cmbox -- category namespace else local nsTable = mw.site.namespaces[ns] if nsTable and nsTable.isTalk then obj.cfg = cfg.tmbox -- any talk namespace else obj.cfg = cfg.ombox -- other namespaces or invalid input end end end -- Set the arguments, and remove all blank arguments except for the ones -- listed in cfg.allowBlankParams. do local newArgs = {} for k, v in pairs(args) do if v ~= '' then newArgs[k] = v end end for i, param in ipairs(obj.cfg.allowBlankParams or {}) do newArgs[param] = args[param] end obj.args = newArgs end -- Define internal data structure. obj.categories = {} obj.classes = {} return setmetatable(obj, MessageBox) end function MessageBox:addCat(ns, cat, sort) if not cat then return nil end if sort then cat = string.format('[[Категория:%s|%s]]', cat, sort) else cat = string.format('[[Категория:%s]]', cat) end self.categories[ns] = self.categories[ns] or {} table.insert(self.categories[ns], cat) end function MessageBox:addClass(class) if not class then return nil end table.insert(self.classes, class) end function MessageBox:setParameters() local args = self.args local cfg = self.cfg -- Get type data. self.type = args.type local typeData = cfg.types[self.type] self.invalidTypeError = cfg.showInvalidTypeError and self.type and not typeData typeData = typeData or cfg.types[cfg.default] self.typeClass = typeData.class self.typeImage = typeData.image -- Find if the box has been wrongly substituted. self.isSubstituted = cfg.substCheck and args.subst == 'SUBST' -- Find whether we are using a small message box. self.isSmall = cfg.allowSmall and ( cfg.smallParam and args.small == cfg.smallParam or not cfg.smallParam and yesno(args.small) ) -- Add attributes, classes and styles. self.id = args.id if yesno(args.plainlinks) ~= false then self:addClass('plainlinks') end if args.mini then self:addClass('ambox-mini') end for _, class in ipairs(cfg.classes or {}) do self:addClass(class) end if self.isSmall then self:addClass(cfg.smallClass or 'mbox-small') end self:addClass(self.typeClass) self:addClass(args.class) self.style = args.style self.attrs = args.attrs self.dataLabel1 = args['data-label-1'] self.dataLabel2 = args['data-label-2'] self.dataLabel3 = args['data-label-3'] self.dataValue1 = args['data-value-1'] self.dataValue2 = args['data-value-2'] self.dataValue3 = args['data-value-3'] -- Set text style. self.textstyle = args.textstyle -- Find if we are on the template page or not. This functionality is only -- used if useCollapsibleTextFields is set, or if both cfg.templateCategory -- and cfg.templateCategoryRequireName are set. self.useCollapsibleTextFields = cfg.useCollapsibleTextFields if self.useCollapsibleTextFields or cfg.templateCategory and cfg.templateCategoryRequireName then self.name = args.name if self.name then local templateName = mw.ustring.match( self.name, '^[tT][eE][mM][pP][lL][aA][tT][eE][%s_]*:[%s_]*(.*)$' ) or self.name templateName = ('Template:' .. templateName) or ('Шаблон:' .. templateName) self.templateTitle = getTitleObject(templateName) end self.isTemplatePage = self.templateTitle and mw.title.equals(self.title, self.templateTitle) end -- Process data for collapsible text fields. At the moment these are only -- used in {{ambox}}. if self.useCollapsibleTextFields then -- Get the self.issue value. if self.isSmall and args.smalltext then self.issue = args.smalltext else local sect if args.sect == '' then sect = '<span style="font-weight:bold">Эта ' .. (cfg.sectionDefault or 'статья') .. '</span>' elseif type(args.sect) == 'string' then sect = '<span style="font-weight:bold">' .. args.sect .. '</span>' end local issue = args.issue issue = type(issue) == 'string' and issue ~= '' and issue or nil local text = args.text text = type(text) == 'string' and text or nil local issues = {} table.insert(issues, sect) table.insert(issues, issue) table.insert(issues, text) self.issue = table.concat(issues, ' ') end -- Get the self.talk value. local talk = args.talk -- Show talk links on the template page or template subpages if the talk -- parameter is blank. if talk == '' and self.templateTitle and ( mw.title.equals(self.templateTitle, self.title) or self.title:isSubpageOf(self.templateTitle) ) then talk = '#' elseif talk == '' then talk = nil end if talk then -- If the talk value is a talk page, make a link to that page. Else -- assume that it's a section heading, and make a link to the talk -- page of the current page with that section heading. local talkTitle = getTitleObject(talk) local talkArgIsTalkPage = true if not talkTitle or not talkTitle.isTalkPage then talkArgIsTalkPage = false talkTitle = getTitleObject( self.title.text, mw.site.namespaces[self.title.namespace].talk.id ) end if talkTitle and talkTitle.exists then local talkText = 'Соответствующую дискуссию можно найти на' if talkArgIsTalkPage then talkText = string.format( '%s [[%s|%s]].', talkText, talk, talkTitle.prefixedText ) else talkText = string.format( '%s [[%s#%s|странице обсуждения]].', talkText, talkTitle.prefixedText, talk ) end self.talk = talkText end end -- Get other values. self.fix = args.fix ~= '' and args.fix or nil local date if args.date and args.date ~= '' then local status, result = pcall(formatDate, args.date) if status then date = string.format("(<span class='date'>%s</span>)", result) else date = string.format("<span class='error'>(Строка «%s» не является верной датой, пожалуйста, укажите дату в формате <code>ГГГГ-ММ-ДД</code>)</span>", args.date) end elseif args.date == '' and self.isTemplatePage then date = string.format("(<span class='date'>%s</span>)", formatDate( lang:formatDate('Y-m-d') ) ) -- тут возникновения ошибки, связанной с пользовательским вводом, не будет end if date then self.date = string.format(" <span class='mbox-date'>''%s''</span>", date) end self.info = args.info if yesno(args.removalnotice) then self.removalNotice = cfg.removalNotice end if args.shortFix then self.shortFix = args.shortFix end end -- Set the non-collapsible text field. At the moment this is used by all box -- types other than ambox, and also by ambox when small=yes. if self.isSmall then self.text = args.smalltext or args.text else self.text = args.text self.textsmall = args['text-small'] end -- Set the below row. self.below = cfg.below and args.below -- General image settings. self.imageCellDiv = not self.isSmall and cfg.imageCellDiv self.imageEmptyCell = cfg.imageEmptyCell if cfg.imageEmptyCellStyle then self.imageEmptyCellStyle = 'border:none;padding:0px;width:1px' end -- Left image settings. local imageLeft = self.isSmall and args.smallimage or args.image if cfg.imageCheckBlank and imageLeft ~= 'blank' and imageLeft ~= 'none' and imageLeft ~= '' or not cfg.imageCheckBlank and imageLeft ~= 'none' then self.imageLeft = imageLeft if not imageLeft then local imageSize = self.isSmall and (cfg.imageSmallSize or '30x30px') or cfg.imageSize or '40x40px' self.imageLeft = string.format('[[File:%s|%s|alt=]]', self.typeImage or 'Information icon4.svg', imageSize) end end -- Right image settings. local imageRight = self.isSmall and args.smallimageright or args.imageright if not (cfg.imageRightNone and imageRight == 'none') then self.imageRight = imageRight end end function MessageBox:setMainspaceCategories() local args = self.args local cfg = self.cfg local date = nil if not cfg.allowMainspaceCategories then return nil end local nums = {} for _, prefix in ipairs{'cat', 'category', 'all'} do args[prefix .. '1'] = args[prefix] nums = union(nums, getArgNums(args, prefix)) end -- The following is roughly equivalent to the old {{Ambox/category}}. local status, result = pcall(formatDate, args.date, 'xg Y') if status then date = result end date = type(date) == 'string' and date local preposition = 'с' local suffix = 'года' for _, num in ipairs(nums) do local mainCat = args['cat' .. tostring(num)] or args['category' .. tostring(num)] local allCat = args['all' .. tostring(num)] mainCat = type(mainCat) == 'string' and mainCat allCat = type(allCat) == 'string' and allCat if mainCat and date and date ~= '' then local catTitle = string.format('%s %s %s %s', mainCat, preposition, date, suffix) self:addCat(0, catTitle) catTitle = getTitleObject('Категория:' .. catTitle) local status, result = pcall(formatDate, args.date) if not status then self:addCat(0, 'Википедия:Статьи с недопустимым параметром даты в шаблоне-сообщении') end elseif mainCat and (not date or date == '') then self:addCat(0, mainCat) end if allCat then self:addCat(0, allCat) end end end function MessageBox:setTemplateCategories() local args = self.args local cfg = self.cfg -- Add template categories. if cfg.templateCategory then if cfg.templateCategoryRequireName then if self.isTemplatePage then self:addCat(10, cfg.templateCategory) end elseif not self.title.isSubpage then self:addCat(10, cfg.templateCategory) end end -- Add template error categories. if cfg.templateErrorCategory then local templateErrorCategory = cfg.templateErrorCategory local templateCat, templateSort if not self.name and not self.title.isSubpage then templateCat = templateErrorCategory elseif self.isTemplatePage then local paramsToCheck = cfg.templateErrorParamsToCheck or {} local count = 0 for i, param in ipairs(paramsToCheck) do if not args[param] then count = count + 1 end end if count > 0 then templateCat = templateErrorCategory templateSort = tostring(count) end if self.categoryNums and #self.categoryNums > 0 then templateCat = templateErrorCategory templateSort = 'C' end end self:addCat(10, templateCat, templateSort) end end function MessageBox:setAllNamespaceCategories() -- Set categories for all namespaces. if self.invalidTypeError then local allSort = (self.title.namespace == 0 and 'Main:' or '') .. self.title.prefixedText self:addCat('all', 'Википедия:Необходимо исправить параметр в шаблоне-сообщении', allSort) end if self.isSubstituted then self:addCat('all', 'Википедия:Страницы с ошибочно подставленными шаблонами') end end function MessageBox:setCategories() if self.title.namespace == 0 then self:setMainspaceCategories() elseif self.title.namespace == 10 then self:setTemplateCategories() end self:setAllNamespaceCategories() end function MessageBox:renderCategories() -- Convert category tables to strings and pass them through -- [[Module:Category handler]]. return categoryHandler{ main = table.concat(self.categories[0] or {}), template = table.concat(self.categories[10] or {}), all = table.concat(self.categories.all or {}), nocat = self.args.nocat, page = self.args.page } end function MessageBox:export() local root = mw.html.create() -- Add the subst check error. if self.isSubstituted and self.name then root:tag('b') :addClass('error') :wikitext(string.format( 'Шаблон <code>%s[[Шаблон:%s|%s]]%s</code> был неккоректно подставлен.', mw.text.nowiki('{{'), self.name, self.name, mw.text.nowiki('}}') )) end -- Create the box table. local boxTable = root:tag('table') boxTable:attr('id', self.id or nil) for i, class in ipairs(self.classes or {}) do boxTable:addClass(class or nil) end boxTable :cssText(self.style or nil) :attr('role', 'presentation') if self.dataLabel1 then boxTable:attr('data-' .. self.dataLabel1, self.dataValue1) end if self.dataLabel2 then boxTable:attr('data-' .. self.dataLabel2, self.dataValue2) end if self.dataLabel3 then boxTable:attr('data-' .. self.dataLabel3, self.dataValue3) end if self.attrs then boxTable:attr(self.attrs) end -- Add the left-hand image. local row = boxTable:tag('tr') if self.imageLeft then local imageLeftCell = row:tag('td'):addClass('mbox-image') if self.imageCellDiv then -- If we are using a div, redefine imageLeftCell so that the image -- is inside it. Divs use style="width: 52px;", which limits the -- image width to 52px. If any images in a div are wider than that, -- they may overlap with the text or cause other display problems. imageLeftCell = imageLeftCell:tag('div'):css('width', '52px') end imageLeftCell:wikitext(self.imageLeft or nil) elseif self.imageEmptyCell then -- Some message boxes define an empty cell if no image is specified, and -- some don't. The old template code in templates where empty cells are -- specified gives the following hint: "No image. Cell with some width -- or padding necessary for text cell to have 100% width." row:tag('td') :addClass('mbox-empty-cell') :cssText(self.imageEmptyCellStyle or nil) end -- Add the text. local textCell = row:tag('td'):addClass('mbox-text') if self.useCollapsibleTextFields then -- The message box uses advanced text parameters that allow things to be -- collapsible. At the moment, only ambox uses this. textCell:cssText(self.textstyle or nil) local textCellDiv = textCell:tag('div') textCellDiv :addClass('mbox-text-div') :wikitext(self.issue or nil) local textsmallCellDiv = textCell:tag('div') textsmallCellDiv :addClass('mbox-textsmall-div hide-when-compact') :cssText(self.textsmallstyle or 'font-size:85%') :wikitext(self.textsmall or nil) if (self.talk or self.fix) and not self.isSmall then textsmallCellDiv:tag('span') :addClass('hide-when-compact') :wikitext(self.talk and (' ' .. self.talk) or nil) :wikitext(self.fix and (' ' .. self.fix) or nil) end textsmallCellDiv:wikitext(self.date and (' ' .. self.date) or nil) if self.info and not self.isSmall then textsmallCellDiv :tag('span') :addClass('hide-when-compact') :wikitext(self.info and (' ' .. self.info) or nil) end if self.removalNotice then textsmallCellDiv:tag('small') :addClass('hide-when-compact') :tag('i') :wikitext(string.format(" (%s)", self.removalNotice)) end if self.shortFix then textCell:tag('div') :addClass('mbox-multiply') :tag('span') :wikitext(string.format("%s", self.shortFix)) :tag('span') :wikitext(self.date and (' ' .. self.date) or nil) end else -- Default text formatting - anything goes. textCell :cssText(self.textstyle or nil) :wikitext(self.text or nil) end -- Add the right-hand image. if self.imageRight then local imageRightCell = row:tag('td'):addClass('mbox-imageright') if self.imageCellDiv then -- If we are using a div, redefine imageRightCell so that the image -- is inside it. imageRightCell = imageRightCell:tag('div'):css('width', '52px') end imageRightCell :wikitext(self.imageRight or nil) end -- Add the below row. if self.below then boxTable:tag('tr') :tag('td') :attr('colspan', self.imageRight and '3' or '2') :addClass('mbox-text') :cssText(self.textstyle or nil) :wikitext(self.below or nil) end -- Add error message for invalid type parameters. if self.invalidTypeError then root:tag('div') :css('text-align', 'center') :wikitext(string.format( 'Этот шаблон-сообщение использует неверный параметр "type=%s", необходимо исправить.', self.type or '' )) end -- Add categories. root:wikitext(self:renderCategories() or nil) return tostring(root) end -------------------------------------------------------------------------------- -- Exports -------------------------------------------------------------------------------- local p, mt = {}, {} function p._exportClasses() -- For testing. return { MessageBox = MessageBox } end function p.main(boxType, args, cfgTables) local box = MessageBox.new(boxType, args, cfgTables or mw.loadData(CONFIG_MODULE)) box:setParameters() box:setCategories() return box:export() end function mt.__index(t, k) return function (frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end return t.main(k, getArgs(frame, {trim = false, removeBlanks = false})) end end return setmetatable(p, mt) f7438b70acb7f9253502968228af5c073b3b1ca5 Модуль:Message box/configuration 828 67 626 107 2024-08-16T16:22:40Z DuOfOrl 5 1 версия импортирована Scribunto text/plain -------------------------------------------------------------------------------- -- Message box configuration -- -- -- -- This module contains configuration data for [[Module:Message box]]. -- -------------------------------------------------------------------------------- return { ambox = { types = { speedy = { class = 'ambox-speedy', image = 'Ambox warning pn.svg' }, delete = { class = 'ambox-delete', image = 'Stop hand nuvola.svg' }, content = { class = 'ambox-content', image = 'Emblem-important.svg' }, style = { class = 'ambox-style', image = 'Broom_icon.svg' }, move = { class = 'ambox-move', image = 'Merge-split-transwiki default.svg' }, protection = { class = 'ambox-protection', image = 'Padlock-silver-medium.svg' }, notice = { class = 'ambox-notice', image = 'Information.svg' }, good = { class = 'ambox-good', image = 'Green star boxed.svg' }, serious = { class = 'ambox-serious', image = 'Stop hand nuvola.svg' }, merge = { class = 'ambox-merge', image = 'Merge-split-transwiki default.svg' }, discussion = { class = 'ambox-discussion', image = 'Nuvola apps ksirc.png' } }, default = 'notice', allowBlankParams = {'talk', 'sect', 'date', 'issue', 'fix', 'subst', 'hidden', 'image'}, allowSmall = true, smallParam = 'left', smallClass = 'mbox-small-left', substCheck = true, classes = {'metadata', 'ambox'}, imageEmptyCell = true, imageCheckBlank = true, imageSmallSize = '20x20px', imageCellDiv = true, useCollapsibleTextFields = true, imageRightNone = true, sectionDefault = 'статья', allowMainspaceCategories = true, templateCategory = 'Шаблоны:Шаблоны-сообщения для статей', templateCategoryRequireName = true, templateErrorCategory = 'Шаблоны:Шаблоны-сообщения для статей с пропущенными параметрами', templateErrorParamsToCheck = {'issue', 'fix'}, removalNotice = '[[Help:Maintenance template removal|Learn how and when to remove this template message]]', templatestyles = 'Module:Message box/ambox.css', }, cmbox = { types = { speedy = { class = 'cmbox-speedy notheme', image = 'Ambox warning pn.svg' }, delete = { class = 'cmbox-delete notheme', image = 'Ambox warning pn.svg' }, content = { class = 'cmbox-content notheme', image = 'Ambox important.svg' }, style = { class = 'cmbox-style notheme', image = 'Edit-clear.svg' }, move = { class = 'cmbox-move notheme', image = 'Merge-split-transwiki default.svg' }, protection = { class = 'cmbox-protection notheme', image = 'Padlock-silver-medium.svg' }, notice = { class = 'cmbox-notice notheme', image = 'Information icon4.svg' } }, default = 'notice', showInvalidTypeError = true, classes = {'cmbox'}, imageEmptyCell = true, useCollapsibleTextFields = true, templatestyles = 'Module:Message box/cmbox.css', }, fmbox = { types = { warning = { class = 'fmbox-warning', image = 'Ambox warning pn.svg' }, editnotice = { class = 'fmbox-editnotice', image = 'Information icon4.svg' }, system = { class = 'fmbox-system', image = 'Information icon4.svg' } }, default = 'system', showInvalidTypeError = true, classes = {'fmbox'}, imageEmptyCell = false, imageRightNone = false, useCollapsibleTextFields = true, templatestyles = 'Module:Message box/fmbox.css', }, imbox = { types = { speedy = { class = 'imbox-speedy', image = 'Ambox warning pn.svg' }, delete = { class = 'imbox-delete', image = 'Ambox warning pn.svg' }, content = { class = 'imbox-content', image = 'Ambox important.svg' }, style = { class = 'imbox-style', image = 'Edit-clear.svg' }, move = { class = 'imbox-move', image = 'Merge-split-transwiki default.svg' }, protection = { class = 'imbox-protection', image = 'Padlock-silver-medium.svg' }, license = { class = 'imbox-license licensetpl', image = 'Imbox license.png' -- @todo We need an SVG version of this }, featured = { class = 'imbox-featured', image = 'Cscr-featured.svg' }, notice = { class = 'imbox-notice', image = 'Information icon4.svg' } }, default = 'notice', showInvalidTypeError = true, classes = {'imbox'}, imageEmptyCell = true, below = true, useCollapsibleTextFields = true, templateCategory = 'Шаблоны:Шаблоны-сообщения для файлов', templatestyles = 'Module:Message box/imbox.css', }, ombox = { types = { speedy = { class = 'ombox-speedy', image = 'OOjs UI icon alert-destructive.svg' }, delete = { class = 'ombox-delete', image = 'OOjs UI icon alert-destructive.svg' }, content = { class = 'ombox-content', image = 'OOjs UI icon notice-warning.svg' }, style = { class = 'ombox-style', image = 'Edit-clear.svg' }, move = { class = 'ombox-move', image = 'Imbox move.png' }, protection = { class = 'ombox-protection', image = 'Imbox protection.png' }, notice = { class = 'ombox-notice', image = 'OOjs UI icon info-progressive.svg' } }, default = 'notice', showInvalidTypeError = true, classes = {'ombox'}, allowSmall = true, imageEmptyCell = true, imageRightNone = true, useCollapsibleTextFields = true, templatestyles = 'Module:Message box/ombox.css', }, tmbox = { types = { speedy = { class = 'tmbox-speedy notheme', image = 'Ambox warning pn.svg' }, delete = { class = 'tmbox-delete notheme', image = 'Ambox warning pn.svg' }, content = { class = 'tmbox-content notheme', image = 'Ambox important.svg' }, style = { class = 'tmbox-style notheme', image = 'Edit-clear.svg' }, move = { class = 'tmbox-move notheme', image = 'Merge-split-transwiki default.svg' }, protection = { class = 'tmbox-protection notheme', image = 'Padlock-silver-medium.svg' }, notice = { class = 'tmbox-notice notheme', image = 'Information icon4.svg' } }, default = 'notice', showInvalidTypeError = true, classes = {'tmbox'}, allowSmall = true, imageRightNone = true, imageEmptyCell = true, imageEmptyCellStyle = true, useCollapsibleTextFields = true, templateCategory = 'Шаблоны:Шаблоны-сообщения для страниц обсуждений', templatestyles = 'Module:Message box/tmbox.css', } } dd71cfc9b05d5244df926bfe86dfdb7ad0e0ff85 661 626 2024-08-16T16:43:22Z DuOfOrl 5 Scribunto text/plain -------------------------------------------------------------------------------- -- Message box configuration -- -- -- -- This module contains configuration data for [[Module:Message box]]. -- -------------------------------------------------------------------------------- return { ambox = { types = { speedy = { class = 'ambox-speedy', image = 'Ambox warning pn.svg' }, delete = { class = 'ambox-delete', image = 'Stop hand nuvola.svg' }, content = { class = 'ambox-content', image = 'Emblem-important.svg' }, style = { class = 'ambox-style', image = 'Broom_icon.svg' }, move = { class = 'ambox-move', image = 'Merge-split-transwiki default.svg' }, protection = { class = 'ambox-protection', image = 'Padlock-silver-medium.svg' }, notice = { class = 'ambox-notice', image = 'Information.svg' }, good = { class = 'ambox-good', image = 'Green star boxed.svg' }, serious = { class = 'ambox-serious', image = 'Stop hand nuvola.svg' }, merge = { class = 'ambox-merge', image = 'Merge-split-transwiki default.svg' }, discussion = { class = 'ambox-discussion', image = 'Nuvola apps ksirc.png' } }, default = 'notice', allowBlankParams = {'talk', 'sect', 'date', 'issue', 'fix', 'subst', 'hidden', 'image'}, allowSmall = true, smallParam = 'left', smallClass = 'mbox-small-left', substCheck = true, classes = {'metadata', 'ambox'}, imageEmptyCell = true, imageCheckBlank = true, imageSmallSize = '20x20px', imageCellDiv = true, useCollapsibleTextFields = true, imageRightNone = true, sectionDefault = 'статья', allowMainspaceCategories = true, templateCategory = 'Шаблоны:Шаблоны-сообщения для статей', templateCategoryRequireName = true, templateErrorCategory = 'Шаблоны:Шаблоны-сообщения для статей с пропущенными параметрами', templateErrorParamsToCheck = {'issue', 'fix'}, removalNotice = '[[Help:Maintenance template removal|Learn how and when to remove this template message]]' }, cmbox = { types = { speedy = { class = 'cmbox-speedy', image = 'Ambox warning pn.svg' }, delete = { class = 'cmbox-delete', image = 'Ambox warning pn.svg' }, content = { class = 'cmbox-content', image = 'Ambox important.svg' }, style = { class = 'cmbox-style', image = 'Edit-clear.svg' }, move = { class = 'cmbox-move', image = 'Merge-split-transwiki default.svg' }, protection = { class = 'cmbox-protection', image = 'Padlock-silver-medium.svg' }, notice = { class = 'cmbox-notice', image = 'Information icon4.svg' } }, default = 'notice', showInvalidTypeError = true, classes = {'cmbox'}, imageEmptyCell = true, useCollapsibleTextFields = true }, fmbox = { types = { warning = { class = 'fmbox-warning', image = 'Ambox warning pn.svg' }, editnotice = { class = 'fmbox-editnotice', image = 'Information icon4.svg' }, system = { class = 'fmbox-system', image = 'Information icon4.svg' } }, default = 'system', showInvalidTypeError = true, classes = {'fmbox'}, imageEmptyCell = false, imageRightNone = false, useCollapsibleTextFields = true }, imbox = { types = { speedy = { class = 'imbox-speedy', image = 'Ambox warning pn.svg' }, delete = { class = 'imbox-delete', image = 'Ambox warning pn.svg' }, content = { class = 'imbox-content', image = 'Ambox important.svg' }, style = { class = 'imbox-style', image = 'Edit-clear.svg' }, move = { class = 'imbox-move', image = 'Merge-split-transwiki default.svg' }, protection = { class = 'imbox-protection', image = 'Padlock-silver-medium.svg' }, license = { class = 'imbox-license licensetpl', image = 'Imbox license.png' -- @todo We need an SVG version of this }, featured = { class = 'imbox-featured', image = 'Cscr-featured.svg' }, notice = { class = 'imbox-notice', image = 'Information icon4.svg' } }, default = 'notice', showInvalidTypeError = true, classes = {'imbox'}, imageEmptyCell = true, below = true, useCollapsibleTextFields = true, templateCategory = 'Шаблоны:Шаблоны-сообщения для файлов' }, ombox = { types = { speedy = { class = 'ombox-speedy', image = 'OOjs UI icon alert-destructive.svg' }, delete = { class = 'ombox-delete', image = 'OOjs UI icon alert-destructive.svg' }, content = { class = 'ombox-content', image = 'OOjs UI icon notice-warning.svg' }, style = { class = 'ombox-style', image = 'Edit-clear.svg' }, move = { class = 'ombox-move', image = 'Imbox move.png' }, protection = { class = 'ombox-protection', image = 'Imbox protection.png' }, notice = { class = 'ombox-notice', image = 'OOjs UI icon info-progressive.svg' } }, default = 'notice', showInvalidTypeError = true, classes = {'ombox'}, allowSmall = true, imageEmptyCell = true, imageRightNone = true, useCollapsibleTextFields = true }, tmbox = { types = { speedy = { class = 'tmbox-speedy', image = 'Ambox warning pn.svg' }, delete = { class = 'tmbox-delete', image = 'Ambox warning pn.svg' }, content = { class = 'tmbox-content', image = 'Ambox important.svg' }, style = { class = 'tmbox-style', image = 'Edit-clear.svg' }, move = { class = 'tmbox-move', image = 'Merge-split-transwiki default.svg' }, protection = { class = 'tmbox-protection', image = 'Padlock-silver-medium.svg' }, notice = { class = 'tmbox-notice', image = 'Information icon4.svg' } }, default = 'notice', showInvalidTypeError = true, classes = {'tmbox'}, allowSmall = true, imageRightNone = true, imageEmptyCell = true, imageEmptyCellStyle = true, useCollapsibleTextFields = true, templateCategory = 'Шаблоны:Шаблоны-сообщения для страниц обсуждений' } } 569b6dcbf9ec9858c77ddf8aefe198cd3f90a950 Модуль:Namespace detect/config 828 77 628 127 2024-08-16T16:22:40Z DuOfOrl 5 1 версия импортирована Scribunto text/plain -------------------------------------------------------------------------------- -- Namespace detect configuration data -- -- -- -- This module stores configuration data for Module:Namespace detect. Here -- -- you can localise the module to your wiki's language. -- -- -- -- To activate a configuration item, you need to uncomment it. This means -- -- that you need to remove the text "-- " at the start of the line. -- -------------------------------------------------------------------------------- local cfg = {} -- Don't edit this line. -------------------------------------------------------------------------------- -- Parameter names -- -- These configuration items specify custom parameter names. Values added -- -- here will work in addition to the default English parameter names. -- -- To add one extra name, you can use this format: -- -- -- -- cfg.foo = 'parameter name' -- -- -- -- To add multiple names, you can use this format: -- -- -- -- cfg.foo = {'parameter name 1', 'parameter name 2', 'parameter name 3'} -- -------------------------------------------------------------------------------- ---- This parameter displays content for the main namespace: -- cfg.main = 'main' ---- This parameter displays in talk namespaces: -- cfg.talk = 'talk' ---- This parameter displays content for "other" namespaces (namespaces for which ---- parameters have not been specified): -- cfg.other = 'other' ---- This parameter makes talk pages behave as though they are the corresponding ---- subject namespace. Note that this parameter is used with [[Module:Yesno]]. ---- Edit that module to change the default values of "yes", "no", etc. -- cfg.subjectns = 'subjectns' ---- This parameter sets a demonstration namespace: -- cfg.demospace = 'demospace' ---- This parameter sets a specific page to compare: cfg.demopage = 'page' -------------------------------------------------------------------------------- -- Table configuration -- -- These configuration items allow customisation of the "table" function, -- -- used to generate a table of possible parameters in the module -- -- documentation. -- -------------------------------------------------------------------------------- ---- The header for the namespace column in the wikitable containing the list of ---- possible subject-space parameters. -- cfg.wikitableNamespaceHeader = 'Namespace' ---- The header for the wikitable containing the list of possible subject-space ---- parameters. -- cfg.wikitableAliasesHeader = 'Aliases' -------------------------------------------------------------------------------- -- End of configuration data -- -------------------------------------------------------------------------------- return cfg -- Don't edit this line. 0e4ff08d13c4b664d66b32c232deb129b77c1a56 Модуль:Namespace detect/data 828 76 630 125 2024-08-16T16:22:41Z DuOfOrl 5 1 версия импортирована Scribunto text/plain -------------------------------------------------------------------------------- -- Namespace detect data -- -- This module holds data for [[Module:Namespace detect]] to be loaded per -- -- page, rather than per #invoke, for performance reasons. -- -------------------------------------------------------------------------------- local cfg = require('Module:Namespace detect/config') local function addKey(t, key, defaultKey) if key ~= defaultKey then t[#t + 1] = key end end -- Get a table of parameters to query for each default parameter name. -- This allows wikis to customise parameter names in the cfg table while -- ensuring that default parameter names will always work. The cfg table -- values can be added as a string, or as an array of strings. local defaultKeys = { 'main', 'talk', 'other', 'subjectns', 'demospace', 'demopage' } local argKeys = {} for i, defaultKey in ipairs(defaultKeys) do argKeys[defaultKey] = {defaultKey} end for defaultKey, t in pairs(argKeys) do local cfgValue = cfg[defaultKey] local cfgValueType = type(cfgValue) if cfgValueType == 'string' then addKey(t, cfgValue, defaultKey) elseif cfgValueType == 'table' then for i, key in ipairs(cfgValue) do addKey(t, key, defaultKey) end end cfg[defaultKey] = nil -- Free the cfg value as we don't need it any more. end local function getParamMappings() --[[ -- Returns a table of how parameter names map to namespace names. The keys -- are the actual namespace names, in lower case, and the values are the -- possible parameter names for that namespace, also in lower case. The -- table entries are structured like this: -- { -- [''] = {'main'}, -- ['wikipedia'] = {'wikipedia', 'project', 'wp'}, -- ... -- } --]] local mappings = {} local mainNsName = mw.site.subjectNamespaces[0].name mainNsName = mw.ustring.lower(mainNsName) mappings[mainNsName] = mw.clone(argKeys.main) mappings['talk'] = mw.clone(argKeys.talk) for nsid, ns in pairs(mw.site.subjectNamespaces) do if nsid ~= 0 then -- Exclude main namespace. local nsname = mw.ustring.lower(ns.name) local canonicalName = mw.ustring.lower(ns.canonicalName) mappings[nsname] = {nsname} if canonicalName ~= nsname then table.insert(mappings[nsname], canonicalName) end for _, alias in ipairs(ns.aliases) do table.insert(mappings[nsname], mw.ustring.lower(alias)) end end end return mappings end return { argKeys = argKeys, cfg = cfg, mappings = getParamMappings() } d224f42a258bc308ef3ad8cc8686cd7a4f47d005 Шаблон:Big 10 73 632 119 2024-08-16T16:22:43Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <span style="font-size:120%;">{{{1}}}</span><noinclude> {{documentation}} <!-- PLEASE ADD CATEGORIES TO THE /doc SUBPAGE, THANKS --> </noinclude> 233a0192f59d7a0c6fef6b818e8d1c96d48295d2 Шаблон:Tag 10 72 634 117 2024-08-16T16:22:43Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{#ifeq: {{{style|}}} | regular | <templatestyles src="Модуль:Template call code/styles.css" /> }}<{{#ifeq: {{{style|}}} | regular | span | code }} class="{{#ifeq: {{{wrap|}}} | yes | wrap | nowrap }}" style="{{#switch: {{{style|}}} | plain = border:none; background:transparent; | regular = | {{{style|}}} }}"><!-- Opening tag -->{{#switch: {{#if: {{{2|}}} | {{{2|}}} | pair }} |c|close = |s|single |o|open |p|pair = {{#ifeq: {{{1|tag}}} | !-- | {{#ifeq: {{{style|}}} | regular | <span class="ts-templateCallCode-weak">&lt;!--</span> | &lt;!-- }} | {{#ifeq: {{{style|}}} | regular | <span class="ts-templateCallCode-weak">&lt;</span> | &lt; }}{{{1|tag}}}{{#if: {{{params|{{{p|}}}}}} | &#32;{{{params|{{{p|}}}}}} }} }} }}<!-- Content between tags -->{{#switch: {{#if: {{{2|}}} | {{{2|}}} | pair }} |c|close = {{{content|{{{c|}}}}}} |s|single = &#32;{{#ifeq: {{{style|}}} | regular | <span class="ts-templateCallCode-weak">/&gt;</span> | /&gt; }} |o|open = {{#ifeq: {{{style|}}} | regular | <span class="ts-templateCallCode-weak">&gt;</span> | &gt; }}{{{content|{{{c|}}}}}} |p|pair = {{#ifeq: {{{1|tag}}} | !-- || {{#ifeq: {{{style|}}} | regular | <span class="ts-templateCallCode-weak">&gt;</span> | &gt; }} }}{{{content|{{{c|}}}}}} }}<!-- Closing tag -->{{#switch: {{#if: {{{2|}}} | {{{2|}}} | pair }} |s|single |o|open = |c|close |p|pair = {{#ifeq: {{{1|tag}}} | !-- | {{#ifeq: {{{style|}}} | regular | <span class="ts-templateCallCode-weak">--&gt;</span> | --&gt; }} | {{#ifeq: {{{style|}}} | regular | <span class="ts-templateCallCode-weak">&lt;/</span>{{{1|tag}}}<span class="ts-templateCallCode-weak">&gt;</span> | &lt;/{{{1|tag}}}&gt; }} }} }}<!-- --></{{#ifeq: {{{style|}}} | regular | span | code }}><noinclude>{{doc}}</noinclude> 2818843691a5275eaf013ee7cc1ac4b87c34f392 Шаблон:Документировать 10 18 636 36 2024-08-16T16:22:44Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{ombox |type = content |text = '''Этому {{#ifeq: {{NAMESPACE}} | Модуль | модулю | шаблону }} не хватает [[Проект:Технические работы/Шаблоны/Документирование|документации]].''' |text-small = Вы можете помочь проекту, {{big|'''[[{{SUBJECTSPACE}}:{{PAGENAME:{{{1|{{SUBJECTPAGENAME}}/doc}}}}}|создав описание {{#ifeq: {{NAMESPACE}} | Модуль | модуля | шаблона }}]]'''}}: что он делает, как его использовать, какие параметры он принимает, в какие категории добавляет. Это поможет другим использовать его. * Не забывайте про [[Проект:Технические работы/Шаблоны/Категоризация|категории]] ({{#ifeq: {{NAMESPACE}} | Модуль || на странице /doc&#32; }}их нужно оборачивать в {{tag|includeonly}}) и интервики. * Некоторые советы по оформлению есть на странице проекта «[[Проект:Технические работы/Шаблоны/Документирование|Документирование шаблонов]]». }}<includeonly>{{#if: {{{nocat|}}}{{#ifeq: {{PAGENAME}} | {{SUBPAGENAME}} || {{#ifeq: {{SUBPAGENAME}} | песочница | nocat }} }} || {{#switch: {{NAMESPACE}} | {{ns:10}} = [[Категория:Шаблоны:Недокументированные]] | {{ns:828}} = {{#ifeq:{{ROOTPAGENAME}}|Песочница||[[Категория:Модули:Недокументированные]]}} }} }}</includeonly><noinclude> {{doc-inline}} Данное сообщение появляется при отсутствующей странице документации, включаемой шаблоном {{t|doc}}. {{doc-end}} [[Категория:Шаблоны:Предупреждения]] [[Категория:Шаблоны:Для документирования шаблонов]] </noinclude> 7779e82507cacf3a1c77cdb878dd6efafd76b3ce Модуль:Infobox 828 211 638 471 2024-08-16T16:34:49Z DuOfOrl 5 1 версия импортирована Scribunto text/plain local p = {}; local yesno = require('Module:Yesno') local function _renderLine( frame, args, i ) if args[ 'заголовок' .. i ] and args[ 'заголовок' .. i ] == '-' then return '' elseif args[ 'заголовок' .. i ] and args[ 'заголовок' .. i ] ~= '' then local style = ( args[ 'стиль_заголовков' ] or '' ) .. ( args[ 'стиль_заголовка' .. i ] or '' ); local class = ( args[ 'класс' .. i ] or '' ); return '\n<tr>\n<th colspan="2" scope="colgroup" class="infobox-header ' .. class .. '" style="' .. style .. '">' .. args[ 'заголовок' .. i ] .. '</th>\n</tr>'; end if args[ 'блок' .. i ] and args[ 'блок' .. i ] ~= '' then return args[ 'блок' .. i ]; end local text = args[ 'текст' .. i ] or ''; if args[ 'викиданные' .. i ] and args[ 'викиданные' .. i ] ~= '' then text = frame:expandTemplate{ title = 'Wikidata', args = { args[ 'викиданные' .. i ], text, from = args[ 'from' ] or '' } }; end if text ~= '' then local label = args[ 'метка' .. i ] or ''; local class = args[ 'класс' .. i ] or ''; if string.find(class, 'noplainlist') == nil and string.find(class, 'nofirstlevel') == nil then class = class .. ' plainlist'; end if class ~= '' then class = ' class="' .. class .. '"'; end local style = ( args[ 'стиль_текстов' ] or '' ) .. ( args[ 'стиль_текста' ] or '' ) .. ( args[ 'стиль_текста' .. i ] or '' ); if label == '' then style = 'text-align:center;' .. style; end if style ~= '' then style = ' style="' .. style .. '"'; end if label ~= '' then local labelClass = args[ 'класс_меток' ] or ''; if string.find(labelClass, 'noplainlist') == nil and string.find(labelClass, 'nofirstlevel') == nil then labelClass = labelClass .. ' plainlist'; end if labelClass ~= '' then labelClass = ' class="' .. labelClass .. '"'; end local labelStyle = ( args[ 'стиль_меток' ] or '' ) .. ( args[ 'стиль_метки' .. i ] or '' ); if labelStyle ~= '' then labelStyle = ' style="' .. labelStyle .. '"'; end return '\n<tr>\n<th scope="row"' .. labelClass .. labelStyle .. '>' .. label .. '</th>' .. '\n<td' .. class .. style .. '>\n' .. text .. '</td>\n</tr>'; end return '\n<tr>\n<td colspan="2"' .. class .. style .. '>\n' .. text .. '</td>\n</tr>'; end return ''; end local function maxNumber ( args ) local maxNumber = 0 for argName, _ in pairs(args) do local argNumber = mw.ustring.match(argName, '^[^0-9]+([0-9]+)$') if argNumber and tonumber(argNumber) > maxNumber then maxNumber = tonumber(argNumber) end end return maxNumber end function p.renderLine( frame ) local args = frame:getParent().args; return _renderLine(frame, args, '') end function p.renderLines( frame ) local args = frame:getParent().args; local res = '' local header, text = '', '' local autoHeaders = yesno(args [ 'автозаголовки' ] or 'false', false) for i = 1, maxNumber(args) do if args[ 'заголовок' .. i ] and args[ 'заголовок' .. i ] ~= '' then if text ~= '' or not autoHeaders then res = res .. header .. text end header, text = _renderLine(frame, args, i), '' else text = text .. _renderLine(frame, args, i) end end if text ~= '' or not autoHeaders then res = res .. header .. text end return res end return p; c830c997bd3d15923f347277e3b0ae71b7ba917e Шаблон:Карточка 10 129 640 606 2024-08-16T16:35:41Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <table class="infobox {{{класс_тела|}}}" style="{{{стиль_тела|}}}" {{#if:{{{имя|}}}|{{#ifeq:{{{имя|}}}|-||data-name="{{{имя}}}"}}}}><!-- Вверху0 -->{{#if:{{{вверху0|}}}|<tr><td colspan="2" class="{{{класс_вверху0|}}}" style="text-align:center; {{{стиль_вверху0|}}}">{{{вверху0}}}</td></tr>}}<!-- Вверху -->{{#if:{{{вверху|}}}|<tr><th colspan="2" class="infobox-above {{{класс_вверху|}}}" style="{{{стиль_вверху|}}}">{{{вверху}}}</th></tr>}}<!-- Вверху2 -->{{#if:{{{вверху2|}}}|<tr><td colspan="2" class="{{{класс_вверху2|}}}" style="text-align:center; {{{стиль_вверху2|}}}">{{{вверху2}}}</td></tr>}}<!-- Вверху3 -->{{#if:{{{вверху3|}}}|<tr><td colspan="2" class="{{{класс_вверху3|}}}" style="text-align:center; {{{стиль_вверху3|}}}">{{{вверху3}}}</td></tr>}}<!-- Изображение -->{{#if:{{{изображение|}}}|<tr><td colspan="2" class="infobox-image {{{класс_изображения|}}}" style="{{{стиль_изображения|}}}"> {{{изображение}}} {{#if:{{{подпись|}}}| <div class="media-caption" style="{{{стиль_подписи|}}}">{{{подпись}}}</div>}}</td></tr>}}<!-- Изображение2 -->{{#if:{{{изображение2|}}}|<tr><td colspan="2" class="infobox-image {{{класс_изображения2|}}}" style="{{{стиль_изображения2|}}}"> {{{изображение2}}} {{#if:{{{подпись2|}}}| <div class="media-caption" style="{{{стиль_подписи2|}}}">{{{подпись2}}}</div>}}</td></tr>}}<!-- Изображение3 -->{{#if:{{{изображение3|}}}|<tr><td colspan="2" class="infobox-image {{{класс_изображения3|}}}" style="{{{стиль_изображения3|}}}"> {{{изображение3}}} {{#if:{{{подпись3|}}}| <div class="media-caption" style="{{{стиль_подписи3|}}}">{{{подпись3}}}</div>}}</td></tr>}}<!-- Строки -->{{#invoke:Infobox|renderLines}}<!-- Внизу -->{{Карточка/внизу| стиль_внизу_общий={{{стиль_внизу|}}}| класс_внизу={{{класс_внизу|}}}| внизу={{{внизу|}}}}}<!-- Внизу N -->{{#invoke:Transclude|npc|Карточка/внизу| стиль_внизу_общий={{{стиль_внизу|}}}| стиль_внизу=| класс_внизу=| внизу=}} </table><includeonly><!-- статьи -->{{#if:{{NAMESPACE}}||<!-- -->{{#if:{{{имя|}}}||[[Категория:Статьи с шаблонами-карточками без имени]]}}<!-- -->{{#ifeq:{{{имя|}}}|{{subst:PAGENAME}}|[[Категория:Статьи с шаблонами-карточками без имени]]}}<!-- -->}}<!-- шаблоны -->{{#ifeq:{{NAMESPACENUMBER}}|10|<!-- -->{{#if:{{{имя|}}}||[[Категория:Шаблоны-карточки без имени]]}}<!-- -->{{#ifeq:{{{имя|}}}|{{subst:PAGENAME}}|[[Категория:Шаблоны-карточки без имени]]}}<!-- -->{{#if:{{{название|}}}{{{стиль_названия|}}}|[[Категория:Шаблоны с использованием параметра «название» в шаблоне «Карточка»]]}}<!-- -->{{#if:{{{подпись|}}}{{{стиль_подписи|}}}{{{подпись2|}}}{{{стиль_подписи2|}}}{{{подпись3|}}}{{{стиль_подписи3|}}}|[[Категория:Шаблоны с использованием параметра «подпись» в шаблоне «Карточка»]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_тела|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_названия|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_вверху|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_вверху2|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_вверху3|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_подписи|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_подписи2|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_подписи3|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_заголовков|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_меток|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_текста|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_внизу|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!-- -->{{#ifeq:{{{имя|}}}|{{PAGENAME}}| [[Категория:Шаблоны-карточки по алфавиту|{{ucfirst:{{без начала|{{PAGENAME}}|Карточка }}}}]]}}<!-- -->}}<!-- любое пространство имён -->{{#if:{{{название|}}}{{{стиль_названия|}}}|[[Категория:Страницы с использованием параметра «название» в шаблоне «Карточка»]]}}<!-- -->{{#if:{{{подпись|}}}{{{стиль_подписи|}}}{{{подпись2|}}}{{{стиль_подписи2|}}}{{{подпись3|}}}{{{стиль_подписи3|}}}|[[Категория:Страницы с использованием параметра «подпись» в шаблоне «Карточка»]]}}</includeonly><noinclude>{{doc}}{{Указание авторства русскоязычной Википедии}}</noinclude> 8b14ccc682362e6ed5a194621133805aea17ab0d Шаблон:OnLua 10 227 642 506 2024-08-16T16:35:45Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki #перенаправление [[Шаблон:Lua]] b72371e7ae22239863c474a78238171c2bd94c7e Шаблон:Tlp 10 217 644 483 2024-08-16T16:35:48Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{{{{|safesubst:}}}#invoke: Template call code | withParams | _link = 1 }}<noinclude>{{doc}}</noinclude> 36c309cb28ccf0901f4fff46cbd35cdabcf00661 Шаблон:Карточка/doc 10 226 646 504 2024-08-16T16:35:50Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{docpage}} {{OnLua|Infobox|renderLines|module2=Transclude|function2=npc}} {{СИШ}} Это меташаблон для создания [[Википедия:Шаблоны-карточки|шаблонов-карточек]]. == Параметры == === Служебные === ; имя: Имя шаблона, необходимое для корректной работы служебных инструментов на всех страницах, где используется шаблон. Для простоты можно использовать <code><nowiki>{{subst:PAGENAME}}</nowiki></code>. ; автозаголовки: Указание «да» приводит к автоматическому скрытию заголовков, после которых, вплоть до следующего заголовка, все поля пусты. Возможно использовать фиктивные заголовки «-» для прерывания области скрытия. Будет работать некорректно, если требуется указать два заголовка подряд — например, при использовании многоуровневых заголовков. В этом случае рекомендуется явно указать «нет» на случай смены значения по умолчанию с «нет» на «да». ; from: Указывается элемент Викиданных, из которого берётся информация. === Основные === ; вверху: Текст, отображаемый вверху таблицы. Обычно это название предмета статьи. ; вверху2: Дополнительный текст, отображаемый вверху таблицы. Обычно используется для оригинального названия. ; вверху3: Дополнительный текст, отображаемый вверху таблицы. ; изображение: Изображение, которое будет отображено под основным заголовком в правой части таблицы (правее заголовков/списков). Параметр ''изображение'' допускает стандартный викикод для отображения. Для разных типов параметра можно использовать {{tl|Форматирование изображения}}. Обычно предпочтительнее использовать код <code><nowiki>{{wikidata|P18|{{{изображение|}}}|caption={{{описание изображения|}}}}}</nowiki></code>. ; подпись: Подпись под изображением. Отображается только в том случае, если задано изображение. При использовании {{tlp|wikidata|P18}} не заполняется. ; изображение2: Дополнительное изображение. ; изображение3: Дополнительное изображение. ; заголовок<sub>n</sub>: Используется для создания заголовков в ряду. Этот и следующие 2 параметра работают при n≥1. ; метка<sub>n</sub>: Используется для подписи текста ; текст<sub>n</sub>: Используется для принятия параметров в специализированных шаблонах-карточках. ; блок<sub>n</sub>: Технический параметр, используется для вставки блоков, заключённых в &#60;tr&#62;, таких как {{t|карточка/блок}}. ; викиданные<sub>n</sub>: Подставляет значение из указанного параметра [[Википедия:Викиданные|Викиданных]] в поле текста, если текст в этой строке определён. Если в поле текста передано значение <code>-</code>, то значение из Викиданных будет скрыто. ; внизу ; внизу<sub>n</sub>: Ячейка во всю ширину таблицы, располагающаяся внизу тела шаблона (то есть под заголовками/метками и текстом). === Стили === ; цвет: Применяется для автоматической раскраски полей «вверху», «внизу» и заголовков через CSS при помощи цветовых тем, имеющихся в шаблоне {{t|Цвет}} ; стиль_тела: Применяется ко всей карточке, обычно используется для указания её ширины, например, <code>width:23em;</code> ; стиль_вверху: Применяется к полю «вверху», например, для указания цвета фона или изменения размера шрифта: <code>font-size:medium;</code> ; стиль_вверху<sub>n</sub>: Используется для изменения стиля дополнительного текста вверху таблицы, например, чтобы убрать курсивное начертание: <code>font-style:normal;</code> ; стиль_изображения: Применяется к ячейке, в которой располагается изображение и его описание ; стиль_изображения<sub>n</sub>: Применяется к ячейке, в которой располагается дополнительное изображение ; стиль_подписи: Применяется к подписи изображения ; стиль_заголовков: С помощью этого стиля можно настроить отображение заголовков, в частности, указать цвет фона: <code>background: #a3eea3;</code> ; стиль_заголовка<sub>n</sub>: Применяется к конкретному заголовку в строке n ; стиль_меток: Применяется к меткам ; стиль_метки<sub>n</sub>: Применяется к конкретной метке в строке n ; стиль_текста: Применяется к тексту ; стиль_текста<sub>n</sub>: Применяется к конкретному тексту в строке n ; стиль_внизу: Эти стили применяются не только в первому ''внизу'', но и ко всем остальным — в отличие от ''стиль_вверху''. ; стиль_внизу<sub>n</sub>: CSS-стили, которые должны быть применены к нижним (указанными параметрами ''внизу'' и ''внизу<sub>n</sub>'') ячейкам. == Возможности == === Сдвоенные ячейки === Если для параметра <code>текст<sub>n</sub></code> значение <code>метка<sub>n</sub></code> не определено, то <code>текст<sub>n</sub></code> автоматически расширяется до 2 ячеек. Для выравнивания по левой стороне можно использовать следующий код: <pre><nowiki> |текст2 = {{{параметр|}}} |стиль_текста2 = text-align:left; </nowiki></pre> === Необязательные ячейки === Ряд с меткой, но без текста не будет отображён. Это позволяет легко создавать необязательные параметры в специализированных шаблонах-карточках. Для создания опциональной ячейки используйте параметр следующим образом: <pre><nowiki> |метка5 = Население |текст5 = {{{население|}}} </nowiki></pre> Таким образом, если параметр <code>население</code> не будет определён, строка «Население» не будет отображена. === Необязательные заголовки === Таким же образом можно организовать необязательные заголовки. Следующий пример будет выводить заголовок «Структура», если задан хотя бы один из параметров <code>содержимое</code>, <code>размещение</code>: <pre><nowiki> |заголовок5 = {{#if:{{{содержимое|}}}{{{размещение|}}}|Структура}} |метка6 = Содержимое |текст6 = {{{содержимое|}}} |метка7 = Размещение |текст7 = {{{размещение|}}} </nowiki></pre> Если есть заголовокN, то текстN и меткаN игнорируются. Если нет заданного заголовкаN, то показываются текстN и меткаN. {| |- |<pre><nowiki> |заголовок1 = {{{заголовок1|}}} |метка1 = {{{метка1|}}} |текст1 = {{{текст1|}}} </nowiki></pre> |} {| |- |<pre><nowiki> |заголовок1 = заголовок_текст |метка1 = метка_текст |текст1 = текст_текст </nowiki></pre> | {| class="wikitable" |- ! заголовок_текст |} |<pre><nowiki> |заголовок1 = |метка1 = метка_текст |текст1 = текст_текст </nowiki></pre> | {| class="wikitable" |- | метка_текст|| текст_текст |} |} === Оформление параметров === Для оформления параметра можно использовать [[Википедия:Функции парсера##if|функцию парсера «#if»]]. Например, следующие строки добавят к параметру <code>текст6</code> подпись кг, если этот параметр определён: <pre><nowiki> |метка6 = Масса |текст6 = {{#if:{{{масса|}}} |{{{масса}}} кг}} </nowiki></pre> А расстановку ссылок на страницы можно организовать с помощью «[[Википедия:Функции парсера##switch:|#switch]]», например: <pre><nowiki> |метка6 = Раса |текст6 = {{#switch:{{{раса|}}} |Европеоиды = [[Европеоидная раса|Европеоиды]] |Негроиды = [[Негроидная раса|Негроиды]] |Монголоиды = [[Монголоидная раса|Монголоиды]] |{{{раса|}}} }} </nowiki></pre> == Пустой шаблон == <pre> {{Карточка |имя = {{subst:PAGENAME}} |автозаголовки = да |стиль_вверху = |стиль_заголовков = |стиль_внизу = |вверху = |вверху2 = |изображение = |заголовок1 = |метка2 = |текст2 = |викиданные2 = |метка3 = |текст3 = |викиданные3 = |метка4 = |текст4 = |викиданные4 = |метка5 = |текст5 = |викиданные5 = |метка6 = |текст6 = |викиданные6 = |метка7 = |текст7 = |викиданные7 = |метка8 = |текст8 = |викиданные8 = |метка9 = |текст9 = |викиданные9 = |метка10 = |текст10 = |викиданные10 = ... |меткаN = |текстN = |викиданныеN = |внизу = }}<noinclude> {{doc}} </noinclude></pre> {{скрытый|Заголовок=11-20|Содержание=<pre> |метка11 = |текст11 = |викиданные11 = |метка12 = |текст12 = |викиданные12 = |метка13 = |текст13 = |викиданные13 = |метка14 = |текст14 = |викиданные14 = |метка15 = |текст15 = |викиданные15 = |метка16 = |текст16 = |викиданные16 = |метка17 = |текст17 = |викиданные17 = |метка18 = |текст18 = |викиданные18 = |метка19 = |текст19 = |викиданные19 = |метка20 = |текст20 = |викиданные20 = </pre>}} {{скрытый||Заголовок=21-30|Содержание=<pre> |метка21 = |текст21 = |викиданные21 = |метка22 = |текст22 = |викиданные22 = |метка23 = |текст23 = |викиданные23 = |метка24 = |текст24 = |викиданные24 = |метка25 = |текст25 = |викиданные25 = |метка26 = |текст26 = |викиданные26 = |метка27 = |текст27 = |викиданные27 = |метка28 = |текст28 = |викиданные28 = |метка29 = |текст29 = |викиданные29 = |метка30 = |текст30 = |викиданные30 = </pre>}} {{скрытый||Заголовок=31-40|Содержание=<pre> |метка31 = |текст31 = |викиданные31 = |метка32 = |текст32 = |викиданные32 = |метка33 = |текст33 = |викиданные33 = |метка34 = |текст34 = |викиданные34 = |метка35 = |текст35 = |викиданные35 = |метка36 = |текст36 = |викиданные36 = |метка37 = |текст37 = |викиданные37 = |метка38 = |текст38 = |викиданные38 = |метка39 = |текст39 = |викиданные39 = |метка40 = |текст40 = |викиданные40 = </pre>}} {{скрытый||Заголовок=41-50|Содержание=<pre> |метка41 = |текст41 = |викиданные41 = |метка42 = |текст42 = |викиданные42 = |метка43 = |текст43 = |викиданные43 = |метка44 = |текст44 = |викиданные44 = |метка45 = |текст45 = |викиданные45 = |метка46 = |текст46 = |викиданные46 = |метка47 = |текст47 = |викиданные47 = |метка48 = |текст48 = |викиданные48 = |метка49 = |текст49 = |викиданные49 = |метка50 = |текст50 = |викиданные50 = </pre>}} {{скрытый||Заголовок=51-60|Содержание=<pre> |метка51 = |текст51 = |викиданные51 = |метка52 = |текст52 = |викиданные52 = |метка53 = |текст53 = |викиданные53 = |метка54 = |текст54 = |викиданные54 = |метка55 = |текст55 = |викиданные55 = |метка56 = |текст56 = |викиданные56 = |метка57 = |текст57 = |викиданные57 = |метка58 = |текст58 = |викиданные58 = |метка59 = |текст59 = |викиданные59 = |метка60 = |текст60 = |викиданные60 = </pre>}} == Примерный шаблон для карточки персоны == <pre>{{Карточка |имя = {{subst:PAGENAME}} |автозаголовки = да |стиль_вверху = |стиль_заголовков = |стиль_внизу = |вверху = {{карточка/имя|{{{имя|}}}}} |вверху2 = {{карточка/оригинал имени|{{{оригинал имени|}}}}} |изображение = {{wikidata|p18|{{{фото|}}}|caption={{{описание изображения|}}}|size={{{ширина|}}}}} |метка1 = Имя при рождении |текст1 = {{{имя при рождении|}}} |викиданные1 = p1477 |метка2 = Дата рождения |текст2 = {{wikidata/p569|{{{дата рождения|}}}|{{{дата смерти|}}}}} |метка3 = Место рождения |текст3 = {{{место рождения|}}} |викиданные3 = p19 |метка4 = Дата смерти |текст4 = {{wikidata/p570|{{{дата смерти|}}}|{{{дата рождения|}}}}} |метка5 = Место смерти |текст5 = {{{место смерти|}}} |викиданные5 = p20 |метка6 = Гражданство |текст6 = {{{гражданство|}}} |викиданные6 = p27 |метка7 = Сценические имена / Прозвище |текст7 = {{{прозвище|}}} |викиданные7 = p1449 |заголовок8 = {{wikidata|p856|{{{сайт|}}}}} |внизу = {{карточка/Викисклад|{{{викисклад|}}}}} }}</pre> Шаблоны {{tl|wikidata/p569}} и {{tl|wikidata/p570}} работают с датами по юлианскому календарю следующим образом: * <code>13.5.1801 (1)</code> будет отображено как [[13 мая|1 (13) мая]] [[1801 год|1801]]; * <code>12.6.1801 (31.5)</code> будет отображено как 31 мая ([[12 июня]]) [[1801 год|1801]]; * <code>12.1.1802 (31.12.1801)</code> будет отображено как 31 декабря 1801 ([[12 января]] [[1802 год|1802]]). == Отслеживающие категории, подставляемые шаблоном == {{Дерево категорий|Отслеживающие категории:Шаблон:Карточка||1|title=}} == См. также == * [[Википедия:Шаблоны-карточки]] * {{t|Универсальная карточка}} * {{t|Навигационная таблица}} — для создания горизонтальных навигационных таблиц (предпочтительнее вертикальных, иногда делаемых на карточке) * [[:Категория:Шаблоны:Подстраницы шаблона Карточка|Подстраницы шаблона Карточка]] * [[Участник:Jack who built the house/alignTemplateParameters.js]] {{Подстраницы шаблона Карточка}} <includeonly> [[Категория:Шаблоны-карточки|*]] [[Категория:Шаблоны:Мета-шаблоны]] </includeonly> f1b3e8ad443b38b993ae6112a8adda8827efe76f Шаблон:Карточка/внизу 10 137 648 317 2024-08-16T16:35:50Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <includeonly>{{#if:{{{внизу|}}}|<tr><td colspan="2" class="infobox-below {{{класс_внизу|}}}" style="{{{стиль_внизу_общий|}}};{{{стиль_внизу|}}}">{{{внизу|}}}</td></tr>}}</includeonly><noinclude> {{doc}} </noinclude> 169fb2d10b0847c2fd677eda9f159ba99025198f Шаблон:Конец скрытого блока 10 199 650 445 2024-08-16T16:35:50Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <includeonly></div></div></includeonly><noinclude> {{doc|Шаблон:Начало скрытого блока/doc}}</noinclude> 2da6ac8eb0812fb4183a70b516009d40920e281f Шаблон:Начало скрытого блока 10 196 652 439 2024-08-16T16:35:51Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <includeonly><templatestyles src="Шаблон:Скрытый блок/styles.css" /><!-- --><div class="mw-collapsible {{#switch: {{{состояние|{{{state|}}}}}} | expanded | autocollapse = {{{состояние|{{{state|}}}}}} | mw-collapsed }} ts-Скрытый_блок ts-Скрытый_блок-{{#switch: {{{тип|{{{type|}}}}}} | gray | transparent = {{{тип|{{{type|}}}}}} | gray }} ts-Скрытый_блок-{{#switch: {{{Ссылка|{{{ссылка|}}}}}} | none = none | right | left = {{{Ссылка|{{{ссылка|}}}}}} | right }}HideLink {{{класс_тела|{{{класс тела|}}}}}}" style="{{ifempty |до = border: | {{{Рамка|{{{border|{{{рамка|}}}}}}}}} |после=;}}{{{frame-style|{{{стиль_тела|{{{стиль тела|}}}}}}}}}"><!-- --><div class="ts-Скрытый_блок-title {{#switch: {{{Выравнивание_заголовка|{{{ta1|{{{выравнивание_заголовка|{{{выравнивание заголовка|}}}}}}}}}}}} | none = none | left | right = ts-Скрытый_блок-title-{{{Выравнивание_заголовка|{{{ta1|{{{выравнивание_заголовка|{{{выравнивание заголовка|}}}}}}}}}}}}Title }} {{{класс_заголовка|{{{класс заголовка|}}}}}}" style="<!-- -->{{ifempty |до = background-color: | {{{Фон_заголовка|{{{bg1|{{{фон_заголовка|{{{фон заголовка|}}}}}}}}}}}} |после=;}}<!-- -->{{ifempty |до = text-align: | {{{Выравнивание_заголовка|{{{ta1|{{{выравнивание_заголовка|{{{выравнивание заголовка|}}}}}}}}}}}} |после=;}}<!-- -->{{ifempty |до = font-weight: | {{{Шрифт_заголовка|{{{шрифт_заголовка|{{{шрифт заголовка|}}}}}}}}} |после=;}}<!-- -->{{ifempty |до = font-style: | {{{Наклон_заголовка|{{{наклон_заголовка|{{{наклон заголовка|}}}}}}}}} |после=;}}<!-- -->{{{Стиль_заголовка|{{{extra1|{{{стиль_заголовка|{{{стиль заголовка|}}}}}}}}}}}}"><!-- -->{{{Заголовок|{{{заголовок|{{{Заглавие|{{{заглавие|{{{Название|{{{название|{{{header|{{{title|{{{1}}}}}}}}}}}}}}}}}}}}}}}}}}}<!-- --><div class="mw-collapsible-toggle-placeholder"></div></div><!-- --><div class="mw-collapsible-content {{{класс_текста|{{{класс текста|}}}}}}" style="<!-- -->{{ifempty |до = background-color: | {{{Фон_текста|{{{bg2|{{{фон_текста|{{{фон текста|}}}}}}}}}}}} |после=;}}<!-- -->{{ifempty |до = font-weight: | {{{Шрифт_текста|{{{шрифт_текста|{{{шрифт текста|}}}}}}}}} |после=;}}<!-- -->{{ifempty |до = font-style: | {{{Наклон_текста|{{{наклон_текста|{{{наклон текста|}}}}}}}}} |после=;}}<!-- -->{{ifempty |до = text-align: | {{{Выравнивание_текста|{{{ta2|{{{выравнивание_текста|{{{выравнивание текста|}}}}}}}}}}}} |после=;}}<!-- -->{{{Стиль_текста|{{{extra2|{{{стиль_текста|{{{стиль текста|}}}}}}}}}}}}"><!-- --></includeonly><noinclude> {{doc}} </noinclude> 3b96bb802b522e629c41cddc5d44dfb2a9eb462a Шаблон:Скрытый 10 203 654 453 2024-08-16T16:35:51Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki #перенаправление [[Шаблон:Скрытый блок]] 97cc939c1c8ece875b2ec360f85980bd6f1bbed7 Шаблон:Скрытый блок 10 200 656 447 2024-08-16T16:35:52Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{Начало скрытого блока |id = {{{id|}}} |тип = {{{тип|{{{type|}}}}}} |состояние = {{{state|{{{состояние|collapsed}}}}}} |класс_тела = {{{класс_тела|{{{класс тела|}}}}}} |стиль_тела = {{{frame-style|{{{стиль_тела|{{{стиль тела|}}}}}}}}} |рамка = {{{Рамка|{{{border|{{{рамка|}}}}}}}}} |заголовок = {{{Заголовок|{{{заголовок|{{{Заглавие|{{{заглавие|{{{Название|{{{название|{{{header|{{{title|{{{1}}}}}}}}}}}}}}}}}}}}}}}}}}} |ссылка = {{{Ссылка|{{{ссылка|}}}}}} |класс_заголовка = {{{класс_заголовка|{{{класс заголовка|}}}}}} |шрифт_заголовка = {{{Шрифт_заголовка|{{{шрифт_заголовка|{{{шрифт заголовка|}}}}}}}}} |наклон_заголовка = {{{Наклон_заголовка|{{{наклон_заголовка|{{{наклон заголовка|}}}}}}}}} |фон_заголовка = {{{Фон_заголовка|{{{bg1|{{{фон_заголовка|{{{фон заголовка|}}}}}}}}}}}} |выравнивание_заголовка = {{{Выравнивание_заголовка|{{{ta1|{{{выравнивание_заголовка|{{{выравнивание заголовка|}}}}}}}}}}}} |стиль_заголовка = {{{title-style|{{{Стиль_заголовка|{{{extra1|{{{стиль_заголовка|{{{стиль заголовка|}}}}}}}}}}}}}}} |класс_текста = {{{класс_текста|{{{класс текста|}}}}}} |шрифт_текста = {{{Шрифт_текста|{{{шрифт_текста|{{{шрифт текста|}}}}}}}}} |наклон_текста = {{{Наклон_текста|{{{наклон_текста|{{{наклон текста|}}}}}}}}} |фон_текста = {{{Фон_текста|{{{bg2|{{{фон_текста|{{{фон текста|}}}}}}}}}}}} |выравнивание_текста = {{{Выравнивание_текста|{{{ta2|{{{выравнивание_текста|{{{выравнивание текста|}}}}}}}}}}}} |стиль_текста = {{{content-style|{{{Стиль_текста|{{{extra2|{{{стиль_текста|{{{стиль текста|}}}}}}}}}}}}}}}}} {{{content|{{{Содержание|{{{содержание|{{{2}}}}}}}}}}}} {{#if: {{{footer|}}} | <div style="{{{footer-style|{{{title-style|}}}}}}">{{{footer}}}</div> }} {{Конец скрытого блока}}<noinclude> {{doc}} </noinclude> 792dc9fb2eb659877e2e758f4ce405e1d3f8352b Модуль:Transclude 828 144 658 331 2024-08-16T16:35:58Z DuOfOrl 5 1 версия импортирована Scribunto text/plain local p={} -- Вызывает внутренний шаблон с аргументами объемлющего шаблона function p.call(frame) local template = frame.args[1] local args = frame:getParent().args return frame:expandTemplate{ title=template, args=args } end -- Общая реализация для forall и call local function forallImpl(args, separator, conjunction, func) -- нумерованные ключи из args local keys = {} -- перебор в произвольном порядке, даже для нумерованных ключей for key, value in pairs(args) do if type(key) == 'number' and value and value ~= '' then table.insert(keys, key) end end table.sort(keys) local results = {} for _, key in ipairs(keys) do local value = func(args[key]) table.insert(results, value) end return mw.text.listToText(results, separator, conjunction) end -- Вызывает внутренний шаблон, передавая ему нумерованные параметры объемлющего шаблона по-одному function p.forall(frame) local template = frame.args[1] local separator = frame.args.separator or '' local conjunction = frame.args.conjunction or separator local args = frame:getParent().args local func = function(value) return frame:expandTemplate{ title = template, args = {value} } -- или другой frame? end return forallImpl(args, separator, conjunction, func) end -- Берёт нумерованные аргументы объемлющего шаблона и склеивает их в единую строку function p.join(frame) local separator = frame.args[1] or '' local conjunction = frame.args[2] or separator local args = frame:getParent().args local func = function(value) return value end return forallImpl(args, separator, conjunction, func) end -- Служебная функция: удаляет дубликаты из отсортированного массива с нумерованными индексами local function deleteDuplicates(args) local res = {} for key, value in pairs(args) do if args[key+1] ~= value then table.insert(res, value) end end return res end -- Вызывает внутренний шаблон несколько раз, передавая в него блоки аргументов объемлющего шаблона function p.npc(frame) local args = frame:getParent().args local templateFrame = frame:getParent() local template = frame.args[1] -- определение, блоки аргументов с какими номерами нужны: -- если в объемлющем шаблоне есть "параметр12" и в вызове модуля есть "параметр", то вызывается 12-й блок local nums = {} for key, _ in pairs(args) do local main, num = string.match(key, '^(.-)%s*(%d*)$') num = tonumber(num) -- учитывать "параметр12", только если задано "параметр" if num and frame.args[main] then table.insert(nums, num) end end table.sort(nums) nums = deleteDuplicates(nums) -- проходить по нужным номерам блоков по возрастанию и однократно -- подставлять в шаблон: -- 1. общие аргументы данного модуля -- 2. аргументы объемлющего шаблона вида "параметр12" как "параметр" в 12-й блок local results = {} for _, blockNum in ipairs(nums) do -- общие аргументы модуля, которые передаются в каждый блок local blockArgs = mw.clone(frame.args) -- metatable ломает expandTemplate setmetatable(blockArgs, nil) for key, value in pairs(args) do local main, num = string.match(key, '^(.-)%s*(%d*)$') num = tonumber(num) -- передавать "параметр12" как "параметр" в 12-й блок, только если есть "параметр" в вызове модуля if blockNum == num and frame.args[main] then blockArgs[main] = value end end local blockText = templateFrame:expandTemplate{ title=template; args=blockArgs } table.insert(results, blockText) end return table.concat(results) end -- Действует аналогично forall по числовой переменной, изменяющейся (по умолчанию, от 1) до f.args[2]. function p.cycle(f) local tf,ac,op=f:getParent(), {}, f.args.output or 'inline'; local sep=''; if op == 'newline' then sep='\n'; end for p,k in pairs(f.args) do if type(p)=='number' then if p>2 then ac[p-1]=k end else ac[p]=k end end local s,fh = f.args[2]:match('^%s*(%-?%d+)%s*%.%.') or 1, f.args[2]:match('%.%.%s*(%S.*)%s*$') or f.args[2] or ''; fh=tonumber(fh) or fh:match('^%s*(.-)%s*$'); s=tonumber(s); local acr={}; if not s then error('Начало цикла «'..s..'» — не число') end local function dc(order) local r=tf:expandTemplate{ title=f.args[1]; args={s,unpack(ac)} } if order == 'desc' then s=s-1; else s=s+1; end if r~='' then table.insert(acr,r); return r end end if type(fh)=='number' then if fh > s then while s<=fh do dc('asc') end else while s>=fh do dc('desc') end end elseif fh~='' then while tf:expandTemplate{ title=fh; args={s,unpack(ac)} } do dc('asc') end else while dc('asc') do end end return table.concat(acr, sep) end return p c17cfab4cebc23157f5ab8d18c7e4f5c273bfa59 Модуль:Template call code 828 126 659 572 2024-08-16T16:38:22Z DuOfOrl 5 Scribunto text/plain local getArgs = require('Module:Arguments').getArgs local ru = mw.language.new('ru') local p = {} -- Используется для того, чтобы можно было удалять элементы из таблицы local function copy(other) local res = {} for k, v in pairs(other) do res[k] = v end return res end local function makeInvokeFunc(funcName) return function (frame) local args = copy(getArgs(frame, { trim = false, removeBlanks = false })) return p[funcName](args) end end p.withoutParams = makeInvokeFunc('_withoutParams') function p._withoutParams(args) local name = args[1] table.remove(args, 1) -- Вещи типа «=» в первом параметре if not name then for k, v in pairs(args) do if not k:find('^_') then name = k .. '=' .. v args[k] = nil break end end end local flags = {} for i, v in ipairs(args) do if v == 'nl' or v == 'nolink' then flags.noLink = true elseif v == 's' then flags.subst = true elseif v == 'п' then flags.podst = true elseif v == 'g' then flags.global = true elseif v == 'nav' then flags.nav = true elseif v == 'noredir' then flags.noRedirect = true elseif v == 'u' then flags.ucFirst = true elseif v == 'b' then flags.black = true end end if name then local trimmedName = mw.text.trim(name) if ru:lc(mw.ustring.sub(trimmedName, 1, 6)) == 'subst:' then flags.subst = true name = mw.ustring.sub(trimmedName, 7) end if ru:lc(mw.ustring.sub(trimmedName, 1, 6)) == 'подст:' then flags.podst = true name = mw.ustring.sub(trimmedName, 7) end end if args.text == '' then args.text = nil end if args.comment == '' then args.comment = nil end if args.lang == '' then args.lang = nil end if args.sister == '' then args.sister = nil end local currentTitle = mw.title.getCurrentTitle() -- При опущенном первом параметре берём имя шаблона из названия страницы if name == '' or not name then local currentTitleRoot = currentTitle.rootText if not flags.ucFirst and ((ru:uc(currentTitleRoot) ~= currentTitleRoot and -- Книга:Литературное наследство, TranslateDate not mw.ustring.match(currentTitleRoot, '^[А-Яа-яA-Za-z]+:?[А-ЯA-Z]') ) or #currentTitleRoot == 1 ) then name = ru:lcfirst(currentTitleRoot) else name = currentTitleRoot end end local global = flags.global or mw.ustring.sub(name, 1, 1) == ':' -- Начинаем собирать код local linkBody, titleObject, linkBegin, linkDivider, linkEnd local prefixes = {} if args.lang then table.insert(prefixes, args.lang) end if args.sister then table.insert(prefixes, args.sister) end linkBody = table.concat(prefixes, ':') if #linkBody ~= 0 then linkBody = ':' .. linkBody end if mw.ustring.sub(name, 1, 1) ~= ':' then linkBody = linkBody .. ':' end if not global then linkBody = linkBody .. 'Template:' end linkBody = linkBody .. name titleObject = mw.title.new(linkBody) local noLink = flags.noLink or currentTitle == titleObject local takeBracketsInLink = not noLink and mw.ustring.len(name) == 1 and not flags.black and not flags.subst and not flags.podst if not noLink then if not flags.noRedirect or ( flags.noRedirect and not args.lang and not args.sister and not titleObject.exists ) then linkBegin = '[[' linkEnd = ']]' linkDivider = '|' else linkBegin = '[' linkEnd = ']' linkDivider = ' ' linkBody = titleObject:fullUrl('redirect=no') end end local text = '' if flags.nav and currentTitle == titleObject then text = text .. '\'\'\'' end if not flags.black then text = text .. '<span class="wp-templatelink">' end text = text .. '{' if not takeBracketsInLink then text = text .. '{' end if flags.subst then text = text .. 'subst:' elseif flags.podst then text = text .. 'подст:' end if not flags.black then text = text .. '</span>' end text = text .. '<span data-navboxnavigation-link="0">' local commentedLabel if args.comment then -- https://phabricator.wikimedia.org/T200704 -- commentedLabel = mw.getCurrentFrame():expandTemplate({title = 'comment', args = {(args.text or name), args.comment}}) commentedLabel = '<span class="commentedText" title="' .. args.comment .. '" style="border-bottom: 1px dotted; cursor: help;">' .. (args.text or name) .. '</span>' end local label = (commentedLabel or args.text or name) if not noLink then if flags.noRedirect then text = text .. '<span class="plainlinks">' end text = text .. linkBegin .. linkBody .. linkDivider if not noLink and takeBracketsInLink then text = text .. '<span class="wp-templatelink">{</span>' end text = text .. label if not noLink and takeBracketsInLink then text = text .. '<span class="wp-templatelink">}</span>' end text = text .. linkEnd if flags.noRedirect then text = text .. '</span>' end else text = text .. label end text = text .. '</span>' if not flags.black then text = text .. '<span class="wp-templatelink">' end text = text .. '}' if not takeBracketsInLink then text = text .. '}' end if not flags.black then text = text .. '</span>' end if flags.nav and currentTitle == titleObject then text = text .. '\'\'\'' end return text end function addParams(args, params) local text, equals_pos, param, value = '', 0, '', '' function addPipe() if params.spaced then text = text .. ' ' end text = text .. '<span' if not params.black then text = text .. ' class="wp-templatelink"' end if not params.spaced then text = text .. ' style="margin:0 2px;"' end text = text .. '>&#124;</span>' end for k, v in pairs(args) do if type(k) == 'number' then -- Неименованные параметры equals_pos = v:find('=') if equals_pos and v:find('{{=}}') == equals_pos - 2 then equals_pos = nil end if equals_pos then -- Содержащие «=» преобразуем в именованные param = v:sub(1, equals_pos - 1) value = v:sub(equals_pos + 1) addPipe() text = text .. param .. '=' .. value else -- Истинно неименованные addPipe() text = text .. v end elseif not k:find('^_') then -- Именованные параметры, исключая модификаторы внешнего вида addPipe() text = text .. k .. '=' .. v end end return text end p.withParams = makeInvokeFunc('_withParams') function p._withParams(args) local name = args[1] table.remove(args, 1) -- Вещи типа «=» в первом параметре if not name then for k, v in pairs(args) do if not k:find('^_') then name = k .. '=' .. v args[k] = nil break end end end local optpText if name then local spanOffset = mw.ustring.find(name, '<span') -- След использования шаблона optp if spanOffset then optpText = mw.ustring.sub(name, spanOffset) name = mw.ustring.sub(name, 1, spanOffset - 1) end end local yesno = require('Module:Yesno') local nobr = yesno(args._nobr, false) local tag = args._tag or 'span' local style = args._style local spaced = yesno(args._spaced, false) local subst = yesno(args._s, false) local podst = yesno(args['_п'], false) local global = yesno(args._g, false) or name and mw.ustring.sub(name, 1, 1) == ':' local lang = args._lang local sister = args._sister local nav = yesno(args._nav, false) local ucFirst = yesno(args._u, false) local black = yesno(args._b, false) or tag ~= 'span' local noLink = yesno(args._nolink or args._nl, false) or not yesno(args._link, false) local textInPlaceOfName = args._text local comment = args._comment local noRedirect = yesno(args._noredir, false) local prefix = args._prefix local postfix = args._postfix if textInPlaceOfName == '' then textInPlaceOfName = nil end if comment == '' then comment = nil end if lang == '' then lang = nil end if sister == '' then sister = nil end if name then local trimmedName = mw.text.trim(name) if ru:lc(mw.ustring.sub(trimmedName, 1, 6)) == 'subst:' then subst = true name = mw.ustring.sub(trimmedName, 7) end if ru:lc(mw.ustring.sub(trimmedName, 1, 6)) == 'подст:' then podst = true name = mw.ustring.sub(trimmedName, 7) end end local currentTitle = mw.title.getCurrentTitle() -- При опущенном первом параметре берём имя шаблона из названия страницы if name == '' or not name then local currentTitleRoot = currentTitle.rootText if not ucFirst and ((ru:uc(currentTitleRoot) ~= currentTitleRoot and -- Книга:Литературное наследство, TranslateDate not mw.ustring.match(currentTitleRoot, '^[А-Яа-яA-Za-z]+:?[А-ЯA-Z]') ) or #currentTitleRoot == 1 ) then name = ru:lcfirst(currentTitleRoot) else name = currentTitleRoot end end -- Начинаем собирать код local linkBody, titleObject, linkBegin, linkDivider, linkEnd local prefixes = {} if lang then table.insert(prefixes, lang) end if sister then table.insert(prefixes, sister) end linkBody = table.concat(prefixes, ':') if #linkBody ~= 0 then linkBody = ':' .. linkBody end if mw.ustring.sub(name, 1, 1) ~= ':' then linkBody = linkBody .. ':' end if not global then linkBody = linkBody .. 'Template:' end linkBody = linkBody .. name titleObject = mw.title.new(linkBody) local noLink = noLink or currentTitle == titleObject local takeBracketsInLink = not noLink and mw.ustring.len(name) == 1 and not black and not subst and not podst if not noLink then if not noRedirect or ( noRedirect and not lang and not sister and not titleObject.exists ) then linkBegin = '[[' linkEnd = ']]' linkDivider = '|' else linkBegin = '[' linkEnd = ']' linkDivider = ' ' linkBody = titleObject:fullUrl('redirect=no') end end local text = '' if tag then text = text .. '<' .. tag .. ' class="templateCallCode' if nobr then text = text .. ' nowrap' end text = text .. '"' if style then text = text .. ' style="' .. style .. '"' end text = text .. '>' end if prefix then text = text .. prefix end if not black then text = text .. '<span class="wp-templatelink">' end text = text .. '{{' if subst then text = text .. 'subst:' elseif podst then text = text .. 'подст:' end if not black then text = text .. '</span>' end if nav and currentTitle == titleObject then text = text .. '\'\'\'' end local commentedLabel if comment then -- https://phabricator.wikimedia.org/T200704 -- commentedLabel = mw.getCurrentFrame():expandTemplate({title = 'comment', args = {(text or name), comment}}) commentedLabel = '<span class="commentedText" title="' .. comment .. '" style="border-bottom: 1px dotted; cursor: help;">' .. (textInPlaceOfName or name) .. '</span>' end local label = (commentedLabel or textInPlaceOfName or name) if not noLink then if noRedirect then text = text .. '<span class="plainlinks">' end text = text .. linkBegin .. linkBody .. linkDivider .. label .. linkEnd if noRedirect then text = text .. '</span>' end else text = text .. label end if nav and currentTitle == titleObject then text = text .. '\'\'\'' end if optpText then text = text .. optpText end text = text .. addParams(args, { spaced = spaced, black = black, }) if spaced then text = text .. ' ' end if not black then text = text .. '<span class="wp-templatelink">' end text = text .. '}}' if not black then text = text .. '</span>' end if postfix then text = text .. postfix end if tag then text = text .. '</' .. tag .. '>' end return text end p.onlyParams = makeInvokeFunc('_onlyParams') function p._onlyParams(args) local span = mw.html.create('span') span:css( 'color', mw.getCurrentFrame():expandTemplate({ title = 'optp/color' }) ) local yesno = require('Module:Yesno') span:wikitext(addParams(args, { spaced = yesno(args._spaced, false), black = true, })) return tostring(span) end return p 0b9f3af403c5d8136788ce6aae12a9b96ee4fe52 Модуль:Navbox 828 82 662 139 2024-08-16T16:47:54Z DuOfOrl 5 Scribunto text/plain -- -- Реализует {{навигационная таблица}}, {{подгруппы навигационной таблицы}} и {{навигационная таблица с блоками}}. -- Основной объём кода заимствован из английского Module:Navbox. -- local p = {} local getArgs -- lazily initialized local yesno -- lazily initialized local styleratio local ODD_EVEN_MARKER = '\127_ODDEVEN_\127' local RESTART_MARKER = '\127_ODDEVEN0_\127' local REGEX_MARKER = '\127_ODDEVEN(%d?)_\127' -- общие параметры для всех шаблонов local commonAliases = { name = {'name', 'имя'}, navigation = {'navigation', 'навигация'}, navbar = {'navbar', 'ссылка_на_просмотр'}, state = {'state'}, orphan = {'orphan'}, tracking = {'tracking'}, border = {'border', 1}, title = {'title', 'заголовок'}, titlegroup = {'titlegroup'}, above = {'above', 'вверху'}, image = {'image', 'изображение'}, imageleft = {'imageleft', 'изображение2', 'изображение_слева'}, below = {'below', 'внизу'}, bodyclass = {'bodyclass', 'класс_тела'}, titleclass = {'titleclass', 'класс_заголовка'}, titlegroupclass = {'titlegroupclass'}, aboveclass = {'aboveclass', 'класс_вверху'}, belowclass = {'belowclass', 'класс_внизу'}, groupclass = {'groupclass', 'класс_групп'}, listclass = {'listclass', 'класс_списков'}, imageclass = {'imageclass', 'класс_изображения'}, basestyle = {'basestyle', 'стиль', 'стиль_базовый'}, bodystyle = {'style', 'bodystyle', 'стиль_тела'}, titlestyle = {'titlestyle', 'стиль_основного_заголовка', 'стиль_заголовка'}, titlegroupstyle = {'titlegroupstyle'}, innerstyle = {'innerstyle'}, abovestyle = {'abovestyle', 'стиль_вверху'}, belowstyle = {'belowstyle', 'стиль_внизу'}, imagestyle = {'imagestyle', 'стиль_изображения'}, imageleftstyle = {'imageleftstyle', 'imagestyle2', 'стиль_изображения_слева'}, } -- параметры {{навигационная таблица}} и {{подгруппы навигационной таблицы}} local standardAliases = { groupstyle = {'groupstyle', 'стиль_заголовков', 'стиль_групп'}, liststyle = {'liststyle', 'стиль_списков'}, evenodd = {'evenodd', 'чётные_нечётные', 'четные_нечетные'}, groupwidth = {'groupwidth', 'ширина_групп'}, listpadding = {'listpadding', 'отступ_списков'}, } -- параметры {{навигационная таблица}} и {{подгруппы навигационной таблицы}} с нумерацией local standardElementAliases = { group = {'group%s', 'заголовок%s', 'группа%s'}, list = {'list%s', 'список%s'}, groupstyle = {'group%sstyle', 'стиль_заголовка%s', 'стиль_группы%s'}, liststyle = {'list%sstyle', 'стиль_списка%s'}, listpadding = {'list%spadding'} } -- параметры {{навигационная таблица с блоками}} -- с нижнего подчеркивания начинаются параметры, конфликтующие с standardAliases local groupsParentAliases = { selected = {'selected', 'открытый_блок', 'развернуть'}, secttitlestyle = {'secttitlestyle', 'стиль_заголовков'}, _groupstyle = {'groupstyle', 'стиль_блоков'}, _liststyle = {'liststyle', 'стиль_списков', 'contentstyle'}, _listpadding = {'listpadding', 'отступ_списка', 'отступ_списков'} } -- параметры {{навигационная таблица с блоками}} с нумерацией local groupsChildAliases = { groupname = {'abbr%s', 'имя_блока%s', 'аббр%s'}, state = {'state%s'}, title = {'group%s', 'блок%s', 'заголовок%s', 'группа%s', 'sect%s', 'section%s', 'секция%s'}, list1 = {'list%s', 'список%s', 'content%s'}, image = {'image%s', 'изображение%s'}, imageleft = {'imageleft%s', 'изображение_слева%s'}, secttitlestyle = {'sect%stitlestyle', 'стиль%sзаголовка', 'стиль_секции%s'}, groupstyle = {'group%sstyle', 'стиль%sблока', 'стиль_группы%s', 'стиль_блока%s'}, liststyle = {'list%sstyle', 'стиль%sсписка', 'стиль_списка%s', 'content%sstyle'}, color = {'цвет%s'} } local function checkAliases(args, aliases, index) for _, alias in ipairs(aliases) do local arg if index then arg = args[string.format(alias, index)] else arg = args[alias] end if arg then return arg end end return nil end local function checkElAliases(args, name, index) return checkAliases(args, standardElementAliases[name], index) end local function concatStyles(t) local res for k, v in pairs(t) do if v then res = res and res .. ';' .. v or v end end return res end local function striped(wikitext, args) -- Return wikitext with markers replaced for odd/even striping. -- Child (subgroup) navboxes are flagged with a category that is removed -- by parent navboxes. The result is that the category shows all pages -- where a child navbox is not contained in a parent navbox. local orphanCat = '[[Категория:Навигационные шаблоны без родителя]]' if args.border == 'subgroup' and args.orphan ~= 'yes' then -- No change; striping occurs in outermost navbox. return wikitext .. orphanCat end local first, second = 'odd', 'even' if args.evenodd then if args.evenodd == 'swap' then first, second = second, first else first = args.evenodd second = first end end local changer if first == second then changer = first else local index = 0 changer = function (code) if code == '0' then -- Current occurrence is for a group before a nested table. -- Set it to first as a valid although pointless class. -- The next occurrence will be the first row after a title -- in a subgroup and will also be first. index = 0 return first end index = index + 1 return index % 2 == 1 and first or second end end local regex = orphanCat:gsub('([%[%]])', '%%%1') return (wikitext:gsub(regex, ''):gsub(REGEX_MARKER, changer)) -- () omits gsub count end local function addNewline(s) if s:match('^[*:;#]') or s:match('^{|') then return '\n' .. s ..'\n' else return s end end local function renderNavBar(titleCell, args) if args.navbar ~= 'off' and args.navbar ~= 'plain' and (args.name or not mw.getCurrentFrame():getParent():getTitle():gsub('/песочница$', '') == 'Шаблон:Навигационная таблица') then -- Check color contrast of the gear icon if not styleratio then styleratio = require('Module:Color contrast')._styleratio end local gearColor = '' local contrastStyle = args.titlestyle or args.basestyle local gearStyleBlack = (contrastStyle and mw.text.unstripNoWiki(contrastStyle) .. '; color:#666;' or '') local gearStyleWhite = (contrastStyle and mw.text.unstripNoWiki(contrastStyle) .. '; color:#fff;' or '') if styleratio{gearStyleBlack} < styleratio{gearStyleWhite} then gearColor = ' white' end local gear = string.format( '[[Файл:Wikipedia interwiki section gear icon%s.svg|14px|Просмотр этого шаблона|link=Шаблон:%s|alt=⛭]]', gearColor, args.name ) --- Gear creation titleCell :tag('span') :addClass('navbox-gear') :css('float', 'left') :css('text-align', 'left') :css('width', '5em') :css('margin-right', '0.5em') :wikitext(gear) end end -- -- Title row -- local function renderTitleRow(tbl, args) if not args.title then return end local titleRow = tbl:tag('tr') if args.titlegroup then titleRow :tag('th') :attr('scope', 'row') :addClass('navbox-group') :addClass(args.titlegroupclass) :cssText(args.basestyle) :cssText(args.groupstyle) :cssText(args.titlegroupstyle) :wikitext(args.titlegroup) end local titleCell = titleRow:tag('th'):attr('scope', 'colgroup') if args.titlegroup then titleCell :css('border-left', '2px solid #fdfdfd') :css('width', '100%') end local titleColspan = 2 if args.imageleft then titleColspan = titleColspan + 1 end if args.image then titleColspan = titleColspan + 1 end if args.titlegroup then titleColspan = titleColspan - 1 end titleCell :cssText(args.basestyle) :cssText(args.titlestyle) :addClass('navbox-title') :attr('colspan', titleColspan) renderNavBar(titleCell, args) titleCell :tag('div') :attr('id', mw.uri.anchorEncode(args.title)) :addClass(args.titleclass) :css('font-size', '114%') :css('margin', '0 5em') :wikitext(addNewline(args.title)) end -- -- Above/Below rows -- local function getAboveBelowColspan(args) local ret = 2 if args.imageleft then ret = ret + 1 end if args.image then ret = ret + 1 end return ret end local function renderAboveRow(tbl, args) if not args.above then return end tbl:tag('tr') :tag('td') :addClass('navbox-abovebelow') :addClass(args.aboveclass) :cssText(args.basestyle) :cssText(args.abovestyle) :attr('colspan', getAboveBelowColspan(args)) :tag('div') :wikitext(addNewline(args.above)) end local function renderBelowRow(tbl, args) if not args.below then return end tbl:tag('tr') :tag('td') :addClass('navbox-abovebelow') :addClass(args.belowclass) :cssText(args.basestyle) :cssText(args.belowstyle) :attr('colspan', getAboveBelowColspan(args)) :tag('div') :wikitext(addNewline(args.below)) end -- -- List rows -- local function haveSubgroups(args) for i = 1, 23 do if checkElAliases(args, 'group', i) and checkElAliases(args, 'list', i) then return true end end return false end local function renderListRow(tbl, args, index, rowspan, rowArgs) local row = tbl:tag('tr') if index == 1 and args.imageleft then row :tag('td') :addClass('navbox-image') :addClass(args.imageclass) :css('width', '1px') :css('padding', '0px 7px 0px 0px') :cssText(args.imageleftstyle) :attr('rowspan', rowspan) :tag('div') :wikitext(addNewline(args.imageleft)) end if rowArgs.group then local groupCell = row:tag('th') groupCell :attr('scope', 'row') :addClass('navbox-group') :addClass(args.groupclass) :cssText(args.basestyle) :css('width', args.groupwidth or '1px') -- If groupwidth not specified, minimize width groupCell :cssText(args.groupstyle) :cssText(rowArgs.groupstyle) :wikitext(rowArgs.group) end local listCell = row:tag('td') if rowArgs.group then listCell :css('text-align', 'left') :css('border-left-width', '2px') :css('border-left-style', 'solid') else if haveSubgroups(args) then listCell :attr('colspan', 2) end end if not args.groupwidth then listCell:css('width', '100%') end local listText = rowArgs.list local oddEven = ODD_EVEN_MARKER if listText:sub(1, 12) == '</div><table' then -- Assume list text is for a subgroup navbox so no automatic striping for this row. oddEven = listText:find('<th[^>]*"navbox%-title"') and RESTART_MARKER or 'odd' end listCell :css('padding', '0px') :cssText(args.liststyle) :cssText(rowArgs.liststyle) :addClass('navbox-list') :addClass('navbox-' .. oddEven) :addClass(args.listclass) :tag('div') :css('padding', rowArgs.listpadding or args.listpadding or '0em 0.25em') :wikitext(addNewline(listText)) if index == 1 and args.image then row :tag('td') :addClass('navbox-image') :addClass(args.imageclass) :css('width', '1px') :css('padding', '0px 0px 0px 7px') :cssText(args.imagestyle) :attr('rowspan', rowspan) :tag('div') :wikitext(addNewline(args.image)) end end -- -- Tracking categories -- local function needsChangetoSubgroups(args) for i = 1, 23 do if (checkElAliases(args, 'group', i)) and not (checkElAliases(args, 'list', i)) then return true end end return false end local function needsHorizontalLists(args) if args.border == 'subgroup' or args.tracking == 'no' then return false end local listClasses = { ['plainlist'] = true, ['hlist'] = true, ['hlist hnum'] = true, ['hlist hwrap'] = true, ['hlist vcard'] = true, ['vcard hlist'] = true, ['hlist vevent'] = true, ['hlist hlist-items-nowrap'] = true, ['hlist-items-nowrap'] = true, } return not (listClasses[args.listclass] or listClasses[args.bodyclass]) end -- local function hasBackgroundColors() -- return mw.ustring.match(titlestyle or '','background') or mw.ustring.match(groupstyle or '','background') or mw.ustring.match(basestyle or '','background') -- end local function isIllegible(args) if not styleratio then styleratio = require('Module:Color contrast')._styleratio end for key, style in pairs(args) do if tostring(key):match("style$") or tostring(key):match("^стиль") then if styleratio{mw.text.unstripNoWiki(style)} < 4.5 then return true end end end return false end local function getTrackingCategories(args) local cats = {} if needsChangetoSubgroups(args) then table.insert(cats, 'Навигационные шаблоны с ошибочным использованием заголовков') end if needsHorizontalLists(args) then table.insert(cats, 'Навигационные шаблоны без горизонтальных списков') end if isIllegible(args) then table.insert(cats, 'Потенциально нечитаемые навигационные шаблоны') end return cats end local function renderTrackingCategories(builder, args) local title = mw.title.getCurrentTitle() if title.namespace ~= 10 then return end -- not in template space local subpage = title.subpageText if subpage == 'doc' or subpage == 'песочница' or subpage == 'тесты' then return end for i, cat in ipairs(getTrackingCategories(args)) do builder:wikitext('[[Категория:' .. cat .. ']]') end end -- -- Main navbox tables -- local function renderMainTable(args, listnums) local tbl = mw.html.create('table') :addClass('nowraplinks') :addClass(args.bodyclass) if args.title and (args.state ~= 'plain' and args.state ~= 'off') then tbl :addClass('collapsible') :addClass(args.state or 'autocollapse') end tbl:css('border-spacing', 0) if args.border == 'subgroup' or args.border == 'none' then tbl :addClass('navbox-subgroup') :cssText(args.bodystyle) else -- regular navbox - bodystyle and style will be applied to the wrapper table tbl :addClass('navbox-inner') :css('background', 'transparent') :css('color', 'inherit') end tbl:cssText(args.innerstyle) renderTitleRow(tbl, args) renderAboveRow(tbl, args) for i, listnum in ipairs(listnums) do local rowArgs = { group = checkElAliases(args, 'group', listnum), list = checkElAliases(args, 'list', listnum), groupstyle = checkElAliases(args, 'groupstyle', listnum), liststyle = checkElAliases(args, 'liststyle', listnum), listpadding = checkElAliases(args, 'listpadding', listnum) } renderListRow(tbl, args, i, #listnums, rowArgs) end renderBelowRow(tbl, args) return tbl end -- Read the arguments in the order they'll be output in, to make references number in the right order. local function readInTheRightOrder(args, groupAliases, listAliases) local _ _ = checkAliases(args, commonAliases.title) _ = checkAliases(args, commonAliases.above) for i = 1, 23 do _ = checkAliases(args, groupAliases, i) _ = checkAliases(args, listAliases, i) end _ = checkAliases(args, commonAliases.below) end function p._navbox(args) if not yesno then yesno = require('Module:Yesno') end local listnums = {} for k, v in pairs(args) do local listnum = ('' .. k):match('^list(%d+)$') or ('' .. k):match('^список(%d+)$') if listnum then table.insert(listnums, tonumber(listnum)) end end table.sort(listnums) args.border = mw.text.trim(args.border or args[1] or '') if args.border == 'child' then args.border = 'subgroup' end for argname, aliasesList in pairs(commonAliases) do args[argname] = checkAliases(args, aliasesList) end for argname, aliasesList in pairs(standardAliases) do args[argname] = checkAliases(args, aliasesList) end args.navigation = yesno(args.navigation, '') -- render the main body of the navbox local tbl = renderMainTable(args, listnums) -- render the appropriate wrapper around the navbox, depending on the border param local res = mw.html.create() if args.border == 'none' then local nav = res:tag('div') :attr('role', 'navigation') :node(tbl) if args.title then nav:attr('aria-labelledby', mw.uri.anchorEncode(args.title)) else nav:attr('aria-label', 'Навигационный шаблон') end if args.name and args.name ~= '-' then nav:attr('data-name', args.name) end if args.navigation == true then nav:attr('data-navboxnavigation', '1') elseif args.navigation == false then nav:attr('data-navboxnavigation', '0') end elseif args.border == 'subgroup' then -- We assume that this navbox is being rendered in a list cell of a parent navbox, and is -- therefore inside a div with padding:0em 0.25em. We start with a </div> to avoid the -- padding being applied, and at the end add a <div> to balance out the parent's </div> res :wikitext('</div>') -- XXX: hack due to lack of unclosed support in mw.html. :node(tbl) :wikitext('<div>') -- XXX: hack due to lack of unclosed support in mw.html. else local nav = res:tag('div') :attr('role', 'navigation') :addClass('navbox') :cssText(args.bodystyle) :css('padding', '3px') :node(tbl) if args.title then nav:attr('aria-labelledby', mw.uri.anchorEncode(args.title)) else nav:attr('aria-label', 'Навигационный шаблон') end if args.name and args.name ~= '-' then nav:attr('data-name', args.name) end if args.navigation == true then nav:attr('data-navboxnavigation', '1') elseif args.navigation == false then nav:attr('data-navboxnavigation', '0') end end renderTrackingCategories(res, args) return striped(tostring(res), args) end function p.navbox(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end if not yesno then yesno = require('Module:Yesno') end args = getArgs(frame, {wrappers = {'Шаблон:Навигационная таблица', 'Шаблон:Подгруппы навигационной таблицы'}}) if frame.args.border then -- This allows Template:Navbox_subgroup to use {{#invoke:Navbox|navbox|border=...}}. args.border = frame.args.border end readInTheRightOrder(args, standardElementAliases.group, standardElementAliases.list) return p._navbox(args) end function p.navboxWithCollapsibleGroups(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end local args = getArgs(frame, {wrappers = {'Шаблон:Навигационная таблица с блоками'}}) readInTheRightOrder(args, groupsChildAliases.title, groupsChildAliases.list1) local parent = {} for argname, aliasesList in pairs(commonAliases) do parent[argname] = checkAliases(args, aliasesList) end for argname, aliasesList in pairs(groupsParentAliases) do parent[argname] = checkAliases(args, aliasesList) end for i = 1, 20 do local child = {} for argname, aliasesList in pairs(groupsChildAliases) do child[argname] = checkAliases(args, aliasesList, i) end child.color = child.color and string.format('background:%s;', child.color) or '' child.border = 'child' child.navbar = 'plain' if parent.selected and parent.selected == child.groupname then child.state = 'uncollapsed' end child.state = child.state or 'collapsed' child.basestyle = concatStyles{parent.basestyle, parent.secttitlestyle, child.secttitlestyle} child.titlestyle = concatStyles{parent._groupstyle, child.groupstyle, child.color} child.liststyle = concatStyles{parent._liststyle, child.liststyle} child.lispadding = parent._listpadding if child.title then parent['list' .. i] = p._navbox(child) else parent['list' .. i] = child.list1 end end return p._navbox(parent) end return p 143824f957f6bf9e642eed17ea875caf2dd8d277 Модуль:Yesno 828 127 663 574 2024-08-16T16:58:46Z DuOfOrl 5 Scribunto text/plain -- Function allowing for consistent treatment of boolean-like wikitext input. -- It works similarly to the template {{yesno}}. return function (val, default) -- If your wiki uses non-ascii characters for any of "yes", "no", etc., you -- should replace "val:lower()" with "mw.ustring.lower(val)" in the -- following line. val = type(val) == 'string' and val:lower() or val if val == nil then return nil elseif val == true or val == 'yes' or val == 'y' or val == 'true' or val == 't' or val == 'да' or val == 'д' or val == '+' or tonumber(val) == 1 then return true elseif val == false or val == 'no' or val == 'n' or val == 'false' or val == 'f' or val == 'нет' or val == 'н' or val == '-' or tonumber(val) == 0 then return false else return default end end 2aa6facc3ee47eb7582d828363d3c1ddc64593d2 Шаблон:Карточка/styles.css 10 252 664 2024-08-16T17:18:58Z DuOfOrl 5 Новая страница: «/* Вынесено из [[MediaWiki:Common.css]] и [[MediaWiki:Mobile.css]] */ .infobox-table, .infobox-tablebox { padding: 0; } .infobox-inner-table, .infobox-table > table, .infobox-tablebox > table { width: 100%; display: table; margin: 0; background: transparent; } .infobox-tablebox > table { border: 1px solid var(--border-color-base, #a2a9b1); border-collapse: separate; } /* Встраиваемая карточка */ .infobox-child { width:...» sanitized-css text/css /* Вынесено из [[MediaWiki:Common.css]] и [[MediaWiki:Mobile.css]] */ .infobox-table, .infobox-tablebox { padding: 0; } .infobox-inner-table, .infobox-table > table, .infobox-tablebox > table { width: 100%; display: table; margin: 0; background: transparent; } .infobox-tablebox > table { border: 1px solid var(--border-color-base, #a2a9b1); border-collapse: separate; } /* Встраиваемая карточка */ .infobox-child { width: 100%; margin: 0; padding: 0; border: none; font-size: 100%; } body.skin-minerva table.infobox-child { width: 100% !important; margin: 0 !important; padding: 0; border: none; font-size: 100%; } /* [[Категория:Шаблоны:Подстраницы CSS]] */ b01ab8a24cfa42c6b091b6ebe1f33dcaf345a6f8 Шаблон:Doc/styles.css 10 173 665 605 2024-08-26T15:40:10Z 176.59.55.152 0 sanitized-css text/css .ts-doc-doc { background-color: var(--background-color-progressive-subtle, #eaf3ff); border: 1px solid var(--border-color-content-added, #afb6e9); clear: both; margin-top: 1em; } /* Ctrl+F ":target" in [[MediaWiki:Common.css]] */ .ts-doc-doc sup.reference:target, .ts-doc-doc ol.references li:target, .ts-doc-doc .highlight-target:target, .ts-doc-doc cite:target, .ts-doc-doc span.citation:target { background: var(--ruwiki-background-color-blue200, #cfe3ff); } .ts-doc-header { align-items: center; background: var(--ruwiki-background-color-blue200, #cfe3ff); display: flex; flex-wrap: wrap; padding: .642857em 1em .5em; overflow: hidden; } .ts-doc-header .ts-tlinks-tlinks { margin-left: auto; } .ts-doc-content { padding: .214286em 1em; } .ts-doc-content:after { content: ''; clear: both; display: block; } .ts-doc-heading { display: inline-block; padding-left: 2em; background: url(//upload.wikimedia.org/wikipedia/commons/c/ca/OOjs_UI_icon_info.svg) center left no-repeat; background-size: contain; font-size: small; min-height: 1.75em; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; } @media screen { html.skin-theme-clientpref-night .ts-doc-heading { background-image: url(//upload.wikimedia.org/wikipedia/commons/c/c0/OOjs_UI_icon_info-invert.svg); } } @media screen and (prefers-color-scheme: dark) { html.skin-theme-clientpref-os .ts-doc-heading { background-image: url(//upload.wikimedia.org/wikipedia/commons/c/c0/OOjs_UI_icon_info-invert.svg); } } .ts-doc-content > *:first-child, .ts-doc-footer > *:first-child { margin-top: .5em; } .ts-doc-content > *:last-child, .ts-doc-footer > *:last-child { margin-bottom: .5em; } .ts-doc-footer { background-color: var(--background-color-progressive-subtle, #eaf3ff); border: 1px solid var(--border-color-content-added, #afb6e9); padding: .214286em 1em; margin-top: .214286em; margin-bottom: .214286em; font-style: italic; } @media (max-width: 719px) { .ts-doc-header { display: block; } .ts-doc-header .ts-tlinks-tlinks { float: none; } } /* [[Категория:Шаблоны:Подстраницы CSS]] */ be8d912472a37a6051bee114da86f913839e7ca0 Шаблон:Карточка/импортёр 10 253 667 666 2024-08-26T15:44:22Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <includeonly>{{ {{{|safesubst:}}}require subst | <noinclude></noinclude>{{Карточка {{subst:!}}{{subst:#if:{{{name|}}} |имя = {{{name}}} {{subst:!}}}}{{subst:#if:{{{bodyclass|}}} |класс_тела = {{{bodyclass}}} {{subst:!}}}}{{subst:#if:{{{bodystyle|}}} |стиль_тела = {{{bodystyle}}} {{subst:!}}}}{{subst:#if:{{{title|}}} |вверху = {{{title}}} {{subst:!}}}}{{subst:#if:{{{titleclass|}}} |класс_вверху = {{{titleclass}}} {{subst:!}}}}{{subst:#if:{{{titlestyle|}}} |стиль_вверху = {{{titlestyle}}} {{subst:!}}}}{{subst:#if:{{{above|}}} |вверху2 = {{{above}}} {{subst:!}}}}{{subst:#if:{{{aboveclass|}}} |класс_вверху2 = {{{aboveclass}}} {{subst:!}}}}{{subst:#if:{{{abovestyle|}}} |стиль_вверху2 = {{{abovestyle}}} {{subst:!}}}}{{subst:#if:{{{image|}}} |изображение = {{{image}}} {{subst:!}}}}{{subst:#if:{{{imageclass|}}} |класс_изображения = {{{imageclass}}} {{subst:!}}}}{{subst:#if:{{{imagestyle|}}} |стиль_изображения = {{{imagestyle}}} {{subst:!}}}}{{subst:#if:{{{caption|}}} |подпись = {{{caption}}} {{subst:!}}}}{{subst:#if:{{{captionstyle|}}} |стиль_подписи = {{{captionstyle}}} {{subst:!}}}}{{subst:#if:{{{headerstyle|}}} |стиль_заголовков = {{{headerstyle}}} {{subst:!}}}}{{subst:#if:{{{labelstyle|}}} |стиль_меток = {{{labelstyle}}} {{subst:!}}}}{{subst:#if:{{{datastyle|}}} |стиль_текста = {{{datastyle}}} {{subst:!}}}}{{subst:#if:{{{header1|}}} |заголовок1 = {{{header1}}} {{subst:!}}}}{{subst:#if:{{{label1|}}} |метка1 = {{{label1}}} {{subst:!}}}}{{subst:#if:{{{data1|}}} |текст1 = {{{data1}}} {{subst:!}}}}{{subst:#if:{{{class1|}}} |класс1 = {{{class1}}} {{subst:!}}}}{{subst:#if:{{{header2|}}} |заголовок2 = {{{header2}}} {{subst:!}}}}{{subst:#if:{{{label2|}}} |метка2 = {{{label2}}} {{subst:!}}}}{{subst:#if:{{{data2|}}} |текст2 = {{{data2}}} {{subst:!}}}}{{subst:#if:{{{class2|}}} |класс2 = {{{class2}}} {{subst:!}}}}{{subst:#if:{{{header3|}}} |заголовок3 = {{{header3}}} {{subst:!}}}}{{subst:#if:{{{label3|}}} |метка3 = {{{label3}}} {{subst:!}}}}{{subst:#if:{{{data3|}}} |текст3 = {{{data3}}} {{subst:!}}}}{{subst:#if:{{{class3|}}} |класс3 = {{{class3}}} {{subst:!}}}}{{subst:#if:{{{header4|}}} |заголовок4 = {{{header4}}} {{subst:!}}}}{{subst:#if:{{{label4|}}} |метка4 = {{{label4}}} {{subst:!}}}}{{subst:#if:{{{data4|}}} |текст4 = {{{data4}}} {{subst:!}}}}{{subst:#if:{{{class4|}}} |класс4 = {{{class4}}} {{subst:!}}}}{{subst:#if:{{{header5|}}} |заголовок5 = {{{header5}}} {{subst:!}}}}{{subst:#if:{{{label5|}}} |метка5 = {{{label5}}} {{subst:!}}}}{{subst:#if:{{{data5|}}} |текст5 = {{{data5}}} {{subst:!}}}}{{subst:#if:{{{class5|}}} |класс5 = {{{class5}}} {{subst:!}}}}{{subst:#if:{{{header6|}}} |заголовок6 = {{{header6}}} {{subst:!}}}}{{subst:#if:{{{label6|}}} |метка6 = {{{label6}}} {{subst:!}}}}{{subst:#if:{{{data6|}}} |текст6 = {{{data6}}} {{subst:!}}}}{{subst:#if:{{{class6|}}} |класс6 = {{{class6}}} {{subst:!}}}}{{subst:#if:{{{header7|}}} |заголовок7 = {{{header7}}} {{subst:!}}}}{{subst:#if:{{{label7|}}} |метка7 = {{{label7}}} {{subst:!}}}}{{subst:#if:{{{data7|}}} |текст7 = {{{data7}}} {{subst:!}}}}{{subst:#if:{{{class7|}}} |класс7 = {{{class7}}} {{subst:!}}}}{{subst:#if:{{{header8|}}} |заголовок8 = {{{header8}}} {{subst:!}}}}{{subst:#if:{{{label8|}}} |метка8 = {{{label8}}} {{subst:!}}}}{{subst:#if:{{{data8|}}} |текст8 = {{{data8}}} {{subst:!}}}}{{subst:#if:{{{class8|}}} |класс8 = {{{class8}}} {{subst:!}}}}{{subst:#if:{{{header9|}}} |заголовок9 = {{{header9}}} {{subst:!}}}}{{subst:#if:{{{label9|}}} |метка9 = {{{label9}}} {{subst:!}}}}{{subst:#if:{{{data9|}}} |текст9 = {{{data9}}} {{subst:!}}}}{{subst:#if:{{{class9|}}} |класс9 = {{{class9}}} {{subst:!}}}}{{subst:#if:{{{header10|}}} |заголовок10 = {{{header10}}} {{subst:!}}}}{{subst:#if:{{{label10|}}} |метка10 = {{{label10}}} {{subst:!}}}}{{subst:#if:{{{data10|}}} |текст10 = {{{data10}}} {{subst:!}}}}{{subst:#if:{{{class10|}}} |класс10 = {{{class10}}} {{subst:!}}}}{{subst:#if:{{{header11|}}} |заголовок11 = {{{header11}}} {{subst:!}}}}{{subst:#if:{{{label11|}}} |метка11 = {{{label11}}} {{subst:!}}}}{{subst:#if:{{{data11|}}} |текст11 = {{{data11}}} {{subst:!}}}}{{subst:#if:{{{class11|}}} |класс11 = {{{class11}}} {{subst:!}}}}{{subst:#if:{{{header12|}}} |заголовок12 = {{{header12}}} {{subst:!}}}}{{subst:#if:{{{label12|}}} |метка12 = {{{label12}}} {{subst:!}}}}{{subst:#if:{{{data12|}}} |текст12 = {{{data12}}} {{subst:!}}}}{{subst:#if:{{{class12|}}} |класс12 = {{{class12}}} {{subst:!}}}}{{subst:#if:{{{header13|}}} |заголовок13 = {{{header13}}} {{subst:!}}}}{{subst:#if:{{{label13|}}} |метка13 = {{{label13}}} {{subst:!}}}}{{subst:#if:{{{data13|}}} |текст13 = {{{data13}}} {{subst:!}}}}{{subst:#if:{{{class13|}}} |класс13 = {{{class13}}} {{subst:!}}}}{{subst:#if:{{{header14|}}} |заголовок14 = {{{header14}}} {{subst:!}}}}{{subst:#if:{{{label14|}}} |метка14 = {{{label14}}} {{subst:!}}}}{{subst:#if:{{{data14|}}} |текст14 = {{{data14}}} {{subst:!}}}}{{subst:#if:{{{class14|}}} |класс14 = {{{class14}}} {{subst:!}}}}{{subst:#if:{{{header15|}}} |заголовок15 = {{{header15}}} {{subst:!}}}}{{subst:#if:{{{label15|}}} |метка15 = {{{label15}}} {{subst:!}}}}{{subst:#if:{{{data15|}}} |текст15 = {{{data15}}} {{subst:!}}}}{{subst:#if:{{{class15|}}} |класс15 = {{{class15}}} {{subst:!}}}}{{subst:#if:{{{header16|}}} |заголовок16 = {{{header16}}} {{subst:!}}}}{{subst:#if:{{{label16|}}} |метка16 = {{{label16}}} {{subst:!}}}}{{subst:#if:{{{data16|}}} |текст16 = {{{data16}}} {{subst:!}}}}{{subst:#if:{{{class16|}}} |класс16 = {{{class16}}} {{subst:!}}}}{{subst:#if:{{{header17|}}} |заголовок17 = {{{header17}}} {{subst:!}}}}{{subst:#if:{{{label17|}}} |метка17 = {{{label17}}} {{subst:!}}}}{{subst:#if:{{{data17|}}} |текст17 = {{{data17}}} {{subst:!}}}}{{subst:#if:{{{class17|}}} |класс17 = {{{class17}}} {{subst:!}}}}{{subst:#if:{{{header18|}}} |заголовок18 = {{{header18}}} {{subst:!}}}}{{subst:#if:{{{label18|}}} |метка18 = {{{label18}}} {{subst:!}}}}{{subst:#if:{{{data18|}}} |текст18 = {{{data18}}} {{subst:!}}}}{{subst:#if:{{{class18|}}} |класс18 = {{{class18}}} {{subst:!}}}}{{subst:#if:{{{header19|}}} |заголовок19 = {{{header19}}} {{subst:!}}}}{{subst:#if:{{{label19|}}} |метка19 = {{{label19}}} {{subst:!}}}}{{subst:#if:{{{data19|}}} |текст19 = {{{data19}}} {{subst:!}}}}{{subst:#if:{{{class19|}}} |класс19 = {{{class19}}} {{subst:!}}}}{{subst:#if:{{{header20|}}} |заголовок20 = {{{header20}}} {{subst:!}}}}{{subst:#if:{{{label20|}}} |метка20 = {{{label20}}} {{subst:!}}}}{{subst:#if:{{{data20|}}} |текст20 = {{{data20}}} {{subst:!}}}}{{subst:#if:{{{class20|}}} |класс20 = {{{class20}}} {{subst:!}}}}{{subst:#if:{{{header21|}}} |заголовок21 = {{{header21}}} {{subst:!}}}}{{subst:#if:{{{label21|}}} |метка21 = {{{label21}}} {{subst:!}}}}{{subst:#if:{{{data21|}}} |текст21 = {{{data21}}} {{subst:!}}}}{{subst:#if:{{{class21|}}} |класс21 = {{{class21}}} {{subst:!}}}}{{subst:#if:{{{header22|}}} |заголовок22 = {{{header22}}} {{subst:!}}}}{{subst:#if:{{{label22|}}} |метка22 = {{{label22}}} {{subst:!}}}}{{subst:#if:{{{data22|}}} |текст22 = {{{data22}}} {{subst:!}}}}{{subst:#if:{{{class22|}}} |класс22 = {{{class22}}} {{subst:!}}}}{{subst:#if:{{{header23|}}} |заголовок23 = {{{header23}}} {{subst:!}}}}{{subst:#if:{{{label23|}}} |метка23 = {{{label23}}} {{subst:!}}}}{{subst:#if:{{{data23|}}} |текст23 = {{{data23}}} {{subst:!}}}}{{subst:#if:{{{class23|}}} |класс23 = {{{class23}}} {{subst:!}}}}{{subst:#if:{{{header24|}}} |заголовок24 = {{{header24}}} {{subst:!}}}}{{subst:#if:{{{label24|}}} |метка24 = {{{label24}}} {{subst:!}}}}{{subst:#if:{{{data24|}}} |текст24 = {{{data24}}} {{subst:!}}}}{{subst:#if:{{{class24|}}} |класс24 = {{{class24}}} {{subst:!}}}}{{subst:#if:{{{header25|}}} |заголовок25 = {{{header25}}} {{subst:!}}}}{{subst:#if:{{{label25|}}} |метка25 = {{{label25}}} {{subst:!}}}}{{subst:#if:{{{data25|}}} |текст25 = {{{data25}}} {{subst:!}}}}{{subst:#if:{{{class25|}}} |класс25 = {{{class25}}} {{subst:!}}}}{{subst:#if:{{{header26|}}} |заголовок26 = {{{header26}}} {{subst:!}}}}{{subst:#if:{{{label26|}}} |метка26 = {{{label26}}} {{subst:!}}}}{{subst:#if:{{{data26|}}} |текст26 = {{{data26}}} {{subst:!}}}}{{subst:#if:{{{class26|}}} |класс26 = {{{class26}}} {{subst:!}}}}{{subst:#if:{{{header27|}}} |заголовок27 = {{{header27}}} {{subst:!}}}}{{subst:#if:{{{label27|}}} |метка27 = {{{label27}}} {{subst:!}}}}{{subst:#if:{{{data27|}}} |текст27 = {{{data27}}} {{subst:!}}}}{{subst:#if:{{{class27|}}} |класс27 = {{{class27}}} {{subst:!}}}}{{subst:#if:{{{header28|}}} |заголовок28 = {{{header28}}} {{subst:!}}}}{{subst:#if:{{{label28|}}} |метка28 = {{{label28}}} {{subst:!}}}}{{subst:#if:{{{data28|}}} |текст28 = {{{data28}}} {{subst:!}}}}{{subst:#if:{{{class28|}}} |класс28 = {{{class28}}} {{subst:!}}}}{{subst:#if:{{{header29|}}} |заголовок29 = {{{header29}}} {{subst:!}}}}{{subst:#if:{{{label29|}}} |метка29 = {{{label29}}} {{subst:!}}}}{{subst:#if:{{{data29|}}} |текст29 = {{{data29}}} {{subst:!}}}}{{subst:#if:{{{class29|}}} |класс29 = {{{class29}}} {{subst:!}}}}{{subst:#if:{{{header30|}}} |заголовок30 = {{{header30}}} {{subst:!}}}}{{subst:#if:{{{label30|}}} |метка30 = {{{label30}}} {{subst:!}}}}{{subst:#if:{{{data30|}}} |текст30 = {{{data30}}} {{subst:!}}}}{{subst:#if:{{{class30|}}} |класс30 = {{{class30}}} {{subst:!}}}}{{subst:#if:{{{header31|}}} |заголовок31 = {{{header31}}} {{subst:!}}}}{{subst:#if:{{{label31|}}} |метка31 = {{{label31}}} {{subst:!}}}}{{subst:#if:{{{data31|}}} |текст31 = {{{data31}}} {{subst:!}}}}{{subst:#if:{{{class31|}}} |класс31 = {{{class31}}} {{subst:!}}}}{{subst:#if:{{{header32|}}} |заголовок32 = {{{header32}}} {{subst:!}}}}{{subst:#if:{{{label32|}}} |метка32 = {{{label32}}} {{subst:!}}}}{{subst:#if:{{{data32|}}} |текст32 = {{{data32}}} {{subst:!}}}}{{subst:#if:{{{class32|}}} |класс32 = {{{class32}}} {{subst:!}}}}{{subst:#if:{{{header33|}}} |заголовок33 = {{{header33}}} {{subst:!}}}}{{subst:#if:{{{label33|}}} |метка33 = {{{label33}}} {{subst:!}}}}{{subst:#if:{{{data33|}}} |текст33 = {{{data33}}} {{subst:!}}}}{{subst:#if:{{{class33|}}} |класс33 = {{{class33}}} {{subst:!}}}}{{subst:#if:{{{header34|}}} |заголовок34 = {{{header34}}} {{subst:!}}}}{{subst:#if:{{{label34|}}} |метка34 = {{{label34}}} {{subst:!}}}}{{subst:#if:{{{data34|}}} |текст34 = {{{data34}}} {{subst:!}}}}{{subst:#if:{{{class34|}}} |класс34 = {{{class34}}} {{subst:!}}}}{{subst:#if:{{{header35|}}} |заголовок35 = {{{header35}}} {{subst:!}}}}{{subst:#if:{{{label35|}}} |метка35 = {{{label35}}} {{subst:!}}}}{{subst:#if:{{{data35|}}} |текст35 = {{{data35}}} {{subst:!}}}}{{subst:#if:{{{class35|}}} |класс35 = {{{class35}}} {{subst:!}}}}{{subst:#if:{{{header36|}}} |заголовок36 = {{{header36}}} {{subst:!}}}}{{subst:#if:{{{label36|}}} |метка36 = {{{label36}}} {{subst:!}}}}{{subst:#if:{{{data36|}}} |текст36 = {{{data36}}} {{subst:!}}}}{{subst:#if:{{{class36|}}} |класс36 = {{{class36}}} {{subst:!}}}}{{subst:#if:{{{header37|}}} |заголовок37 = {{{header37}}} {{subst:!}}}}{{subst:#if:{{{label37|}}} |метка37 = {{{label37}}} {{subst:!}}}}{{subst:#if:{{{data37|}}} |текст37 = {{{data37}}} {{subst:!}}}}{{subst:#if:{{{class37|}}} |класс37 = {{{class37}}} {{subst:!}}}}{{subst:#if:{{{header38|}}} |заголовок38 = {{{header38}}} {{subst:!}}}}{{subst:#if:{{{label38|}}} |метка38 = {{{label38}}} {{subst:!}}}}{{subst:#if:{{{data38|}}} |текст38 = {{{data38}}} {{subst:!}}}}{{subst:#if:{{{class38|}}} |класс38 = {{{class38}}} {{subst:!}}}}{{subst:#if:{{{header39|}}} |заголовок39 = {{{header39}}} {{subst:!}}}}{{subst:#if:{{{label39|}}} |метка39 = {{{label39}}} {{subst:!}}}}{{subst:#if:{{{data39|}}} |текст39 = {{{data39}}} {{subst:!}}}}{{subst:#if:{{{class39|}}} |класс39 = {{{class39}}} {{subst:!}}}}{{subst:#if:{{{header40|}}} |заголовок40 = {{{header40}}} {{subst:!}}}}{{subst:#if:{{{label40|}}} |метка40 = {{{label40}}} {{subst:!}}}}{{subst:#if:{{{data40|}}} |текст40 = {{{data40}}} {{subst:!}}}}{{subst:#if:{{{class40|}}} |класс40 = {{{class40}}} {{subst:!}}}}{{subst:#if:{{{header41|}}} |заголовок41 = {{{header41}}} {{subst:!}}}}{{subst:#if:{{{label41|}}} |метка41 = {{{label41}}} {{subst:!}}}}{{subst:#if:{{{data41|}}} |текст41 = {{{data41}}} {{subst:!}}}}{{subst:#if:{{{class41|}}} |класс41 = {{{class41}}} {{subst:!}}}}{{subst:#if:{{{header42|}}} |заголовок42 = {{{header42}}} {{subst:!}}}}{{subst:#if:{{{label42|}}} |метка42 = {{{label42}}} {{subst:!}}}}{{subst:#if:{{{data42|}}} |текст42 = {{{data42}}} {{subst:!}}}}{{subst:#if:{{{class42|}}} |класс42 = {{{class42}}} {{subst:!}}}}{{subst:#if:{{{header43|}}} |заголовок43 = {{{header43}}} {{subst:!}}}}{{subst:#if:{{{label43|}}} |метка43 = {{{label43}}} {{subst:!}}}}{{subst:#if:{{{data43|}}} |текст43 = {{{data43}}} {{subst:!}}}}{{subst:#if:{{{class43|}}} |класс43 = {{{class43}}} {{subst:!}}}}{{subst:#if:{{{header44|}}} |заголовок44 = {{{header44}}} {{subst:!}}}}{{subst:#if:{{{label44|}}} |метка44 = {{{label44}}} {{subst:!}}}}{{subst:#if:{{{data44|}}} |текст44 = {{{data44}}} {{subst:!}}}}{{subst:#if:{{{class44|}}} |класс44 = {{{class44}}} {{subst:!}}}}{{subst:#if:{{{header45|}}} |заголовок45 = {{{header45}}} {{subst:!}}}}{{subst:#if:{{{label45|}}} |метка45 = {{{label45}}} {{subst:!}}}}{{subst:#if:{{{data45|}}} |текст45 = {{{data45}}} {{subst:!}}}}{{subst:#if:{{{class45|}}} |класс45 = {{{class45}}} {{subst:!}}}}{{subst:#if:{{{header46|}}} |заголовок46 = {{{header46}}} {{subst:!}}}}{{subst:#if:{{{label46|}}} |метка46 = {{{label46}}} {{subst:!}}}}{{subst:#if:{{{data46|}}} |текст46 = {{{data46}}} {{subst:!}}}}{{subst:#if:{{{class46|}}} |класс46 = {{{class46}}} {{subst:!}}}}{{subst:#if:{{{header47|}}} |заголовок47 = {{{header47}}} {{subst:!}}}}{{subst:#if:{{{label47|}}} |метка47 = {{{label47}}} {{subst:!}}}}{{subst:#if:{{{data47|}}} |текст47 = {{{data47}}} {{subst:!}}}}{{subst:#if:{{{class47|}}} |класс47 = {{{class47}}} {{subst:!}}}}{{subst:#if:{{{header48|}}} |заголовок48 = {{{header48}}} {{subst:!}}}}{{subst:#if:{{{label48|}}} |метка48 = {{{label48}}} {{subst:!}}}}{{subst:#if:{{{data48|}}} |текст48 = {{{data48}}} {{subst:!}}}}{{subst:#if:{{{class48|}}} |класс48 = {{{class48}}} {{subst:!}}}}{{subst:#if:{{{header49|}}} |заголовок49 = {{{header49}}} {{subst:!}}}}{{subst:#if:{{{label49|}}} |метка49 = {{{label49}}} {{subst:!}}}}{{subst:#if:{{{data49|}}} |текст49 = {{{data49}}} {{subst:!}}}}{{subst:#if:{{{class49|}}} |класс49 = {{{class49}}} {{subst:!}}}}{{subst:#if:{{{header50|}}} |заголовок50 = {{{header50}}} {{subst:!}}}}{{subst:#if:{{{label50|}}} |метка50 = {{{label50}}} {{subst:!}}}}{{subst:#if:{{{data50|}}} |текст50 = {{{data50}}} {{subst:!}}}}{{subst:#if:{{{class50|}}} |класс50 = {{{class50}}} {{subst:!}}}}{{subst:#if:{{{header51|}}} |заголовок51 = {{{header51}}} {{subst:!}}}}{{subst:#if:{{{label51|}}} |метка51 = {{{label51}}} {{subst:!}}}}{{subst:#if:{{{data51|}}} |текст51 = {{{data51}}} {{subst:!}}}}{{subst:#if:{{{class51|}}} |класс51 = {{{class51}}} {{subst:!}}}}{{subst:#if:{{{header52|}}} |заголовок52 = {{{header52}}} {{subst:!}}}}{{subst:#if:{{{label52|}}} |метка52 = {{{label52}}} {{subst:!}}}}{{subst:#if:{{{data52|}}} |текст52 = {{{data52}}} {{subst:!}}}}{{subst:#if:{{{class52|}}} |класс52 = {{{class52}}} {{subst:!}}}}{{subst:#if:{{{header53|}}} |заголовок53 = {{{header53}}} {{subst:!}}}}{{subst:#if:{{{label53|}}} |метка53 = {{{label53}}} {{subst:!}}}}{{subst:#if:{{{data53|}}} |текст53 = {{{data53}}} {{subst:!}}}}{{subst:#if:{{{class53|}}} |класс53 = {{{class53}}} {{subst:!}}}}{{subst:#if:{{{header54|}}} |заголовок54 = {{{header54}}} {{subst:!}}}}{{subst:#if:{{{label54|}}} |метка54 = {{{label54}}} {{subst:!}}}}{{subst:#if:{{{data54|}}} |текст54 = {{{data54}}} {{subst:!}}}}{{subst:#if:{{{class54|}}} |класс54 = {{{class54}}} {{subst:!}}}}{{subst:#if:{{{header55|}}} |заголовок55 = {{{header55}}} {{subst:!}}}}{{subst:#if:{{{label55|}}} |метка55 = {{{label55}}} {{subst:!}}}}{{subst:#if:{{{data55|}}} |текст55 = {{{data55}}} {{subst:!}}}}{{subst:#if:{{{class55|}}} |класс55 = {{{class55}}} {{subst:!}}}}{{subst:#if:{{{header56|}}} |заголовок56 = {{{header56}}} {{subst:!}}}}{{subst:#if:{{{label56|}}} |метка56 = {{{label56}}} {{subst:!}}}}{{subst:#if:{{{data56|}}} |текст56 = {{{data56}}} {{subst:!}}}}{{subst:#if:{{{class56|}}} |класс56 = {{{class56}}} {{subst:!}}}}{{subst:#if:{{{header57|}}} |заголовок57 = {{{header57}}} {{subst:!}}}}{{subst:#if:{{{label57|}}} |метка57 = {{{label57}}} {{subst:!}}}}{{subst:#if:{{{data57|}}} |текст57 = {{{data57}}} {{subst:!}}}}{{subst:#if:{{{class57|}}} |класс57 = {{{class57}}} {{subst:!}}}}{{subst:#if:{{{header58|}}} |заголовок58 = {{{header58}}} {{subst:!}}}}{{subst:#if:{{{label58|}}} |метка58 = {{{label58}}} {{subst:!}}}}{{subst:#if:{{{data58|}}} |текст58 = {{{data58}}} {{subst:!}}}}{{subst:#if:{{{class58|}}} |класс58 = {{{class58}}} {{subst:!}}}}{{subst:#if:{{{header59|}}} |заголовок59 = {{{header59}}} {{subst:!}}}}{{subst:#if:{{{label59|}}} |метка59 = {{{label59}}} {{subst:!}}}}{{subst:#if:{{{data59|}}} |текст59 = {{{data59}}} {{subst:!}}}}{{subst:#if:{{{class59|}}} |класс59 = {{{class59}}} {{subst:!}}}}{{subst:#if:{{{header60|}}} |заголовок60 = {{{header60}}} {{subst:!}}}}{{subst:#if:{{{label60|}}} |метка60 = {{{label60}}} {{subst:!}}}}{{subst:#if:{{{data60|}}} |текст60 = {{{data60}}} {{subst:!}}}}{{subst:#if:{{{class60|}}} |класс60 = {{{class60}}} {{subst:!}}}}{{subst:#if:{{{header61|}}} |заголовок61 = {{{header61}}} {{subst:!}}}}{{subst:#if:{{{label61|}}} |метка61 = {{{label61}}} {{subst:!}}}}{{subst:#if:{{{data61|}}} |текст61 = {{{data61}}} {{subst:!}}}}{{subst:#if:{{{class61|}}} |класс61 = {{{class61}}} {{subst:!}}}}{{subst:#if:{{{header62|}}} |заголовок62 = {{{header62}}} {{subst:!}}}}{{subst:#if:{{{label62|}}} |метка62 = {{{label62}}} {{subst:!}}}}{{subst:#if:{{{data62|}}} |текст62 = {{{data62}}} {{subst:!}}}}{{subst:#if:{{{class62|}}} |класс62 = {{{class62}}} {{subst:!}}}}{{subst:#if:{{{header63|}}} |заголовок63 = {{{header63}}} {{subst:!}}}}{{subst:#if:{{{label63|}}} |метка63 = {{{label63}}} {{subst:!}}}}{{subst:#if:{{{data63|}}} |текст63 = {{{data63}}} {{subst:!}}}}{{subst:#if:{{{class63|}}} |класс63 = {{{class63}}} {{subst:!}}}}{{subst:#if:{{{header64|}}} |заголовок64 = {{{header64}}} {{subst:!}}}}{{subst:#if:{{{label64|}}} |метка64 = {{{label64}}} {{subst:!}}}}{{subst:#if:{{{data64|}}} |текст64 = {{{data64}}} {{subst:!}}}}{{subst:#if:{{{class64|}}} |класс64 = {{{class64}}} {{subst:!}}}}{{subst:#if:{{{header65|}}} |заголовок65 = {{{header65}}} {{subst:!}}}}{{subst:#if:{{{label65|}}} |метка65 = {{{label65}}} {{subst:!}}}}{{subst:#if:{{{data65|}}} |текст65 = {{{data65}}} {{subst:!}}}}{{subst:#if:{{{class65|}}} |класс65 = {{{class65}}} {{subst:!}}}}{{subst:#if:{{{header66|}}} |заголовок66 = {{{header66}}} {{subst:!}}}}{{subst:#if:{{{label66|}}} |метка66 = {{{label66}}} {{subst:!}}}}{{subst:#if:{{{data66|}}} |текст66 = {{{data66}}} {{subst:!}}}}{{subst:#if:{{{class66|}}} |класс66 = {{{class66}}} {{subst:!}}}}{{subst:#if:{{{header67|}}} |заголовок67 = {{{header67}}} {{subst:!}}}}{{subst:#if:{{{label67|}}} |метка67 = {{{label67}}} {{subst:!}}}}{{subst:#if:{{{data67|}}} |текст67 = {{{data67}}} {{subst:!}}}}{{subst:#if:{{{class67|}}} |класс67 = {{{class67}}} {{subst:!}}}}{{subst:#if:{{{header68|}}} |заголовок68 = {{{header68}}} {{subst:!}}}}{{subst:#if:{{{label68|}}} |метка68 = {{{label68}}} {{subst:!}}}}{{subst:#if:{{{data68|}}} |текст68 = {{{data68}}} {{subst:!}}}}{{subst:#if:{{{class68|}}} |класс68 = {{{class68}}} {{subst:!}}}}{{subst:#if:{{{header69|}}} |заголовок69 = {{{header69}}} {{subst:!}}}}{{subst:#if:{{{label69|}}} |метка69 = {{{label69}}} {{subst:!}}}}{{subst:#if:{{{data69|}}} |текст69 = {{{data69}}} {{subst:!}}}}{{subst:#if:{{{class69|}}} |класс69 = {{{class69}}} {{subst:!}}}}{{subst:#if:{{{header70|}}} |заголовок70 = {{{header70}}} {{subst:!}}}}{{subst:#if:{{{label70|}}} |метка70 = {{{label70}}} {{subst:!}}}}{{subst:#if:{{{data70|}}} |текст70 = {{{data70}}} {{subst:!}}}}{{subst:#if:{{{class70|}}} |класс70 = {{{class70}}} {{subst:!}}}}{{subst:#if:{{{header71|}}} |заголовок71 = {{{header71}}} {{subst:!}}}}{{subst:#if:{{{label71|}}} |метка71 = {{{label71}}} {{subst:!}}}}{{subst:#if:{{{data71|}}} |текст71 = {{{data71}}} {{subst:!}}}}{{subst:#if:{{{class71|}}} |класс71 = {{{class71}}} {{subst:!}}}}{{subst:#if:{{{header72|}}} |заголовок72 = {{{header72}}} {{subst:!}}}}{{subst:#if:{{{label72|}}} |метка72 = {{{label72}}} {{subst:!}}}}{{subst:#if:{{{data72|}}} |текст72 = {{{data72}}} {{subst:!}}}}{{subst:#if:{{{class72|}}} |класс72 = {{{class72}}} {{subst:!}}}}{{subst:#if:{{{header73|}}} |заголовок73 = {{{header73}}} {{subst:!}}}}{{subst:#if:{{{label73|}}} |метка73 = {{{label73}}} {{subst:!}}}}{{subst:#if:{{{data73|}}} |текст73 = {{{data73}}} {{subst:!}}}}{{subst:#if:{{{class73|}}} |класс73 = {{{class73}}} {{subst:!}}}}{{subst:#if:{{{header74|}}} |заголовок74 = {{{header74}}} {{subst:!}}}}{{subst:#if:{{{label74|}}} |метка74 = {{{label74}}} {{subst:!}}}}{{subst:#if:{{{data74|}}} |текст74 = {{{data74}}} {{subst:!}}}}{{subst:#if:{{{class74|}}} |класс74 = {{{class74}}} {{subst:!}}}}{{subst:#if:{{{header75|}}} |заголовок75 = {{{header75}}} {{subst:!}}}}{{subst:#if:{{{label75|}}} |метка75 = {{{label75}}} {{subst:!}}}}{{subst:#if:{{{data75|}}} |текст75 = {{{data75}}} {{subst:!}}}}{{subst:#if:{{{class75|}}} |класс75 = {{{class75}}} {{subst:!}}}}{{subst:#if:{{{header76|}}} |заголовок76 = {{{header76}}} {{subst:!}}}}{{subst:#if:{{{label76|}}} |метка76 = {{{label76}}} {{subst:!}}}}{{subst:#if:{{{data76|}}} |текст76 = {{{data76}}} {{subst:!}}}}{{subst:#if:{{{class76|}}} |класс76 = {{{class76}}} {{subst:!}}}}{{subst:#if:{{{header77|}}} |заголовок77 = {{{header77}}} {{subst:!}}}}{{subst:#if:{{{label77|}}} |метка77 = {{{label77}}} {{subst:!}}}}{{subst:#if:{{{data77|}}} |текст77 = {{{data77}}} {{subst:!}}}}{{subst:#if:{{{class77|}}} |класс77 = {{{class77}}} {{subst:!}}}}{{subst:#if:{{{header78|}}} |заголовок78 = {{{header78}}} {{subst:!}}}}{{subst:#if:{{{label78|}}} |метка78 = {{{label78}}} {{subst:!}}}}{{subst:#if:{{{data78|}}} |текст78 = {{{data78}}} {{subst:!}}}}{{subst:#if:{{{class78|}}} |класс78 = {{{class78}}} {{subst:!}}}}{{subst:#if:{{{header79|}}} |заголовок79 = {{{header79}}} {{subst:!}}}}{{subst:#if:{{{label79|}}} |метка79 = {{{label79}}} {{subst:!}}}}{{subst:#if:{{{data79|}}} |текст79 = {{{data79}}} {{subst:!}}}}{{subst:#if:{{{class79|}}} |класс79 = {{{class79}}} {{subst:!}}}}{{subst:#if:{{{header80|}}} |заголовок80 = {{{header80}}} {{subst:!}}}}{{subst:#if:{{{label80|}}} |метка80 = {{{label80}}} {{subst:!}}}}{{subst:#if:{{{data80|}}} |текст80 = {{{data80}}} {{subst:!}}}}{{subst:#if:{{{class80|}}} |класс80 = {{{class80}}} {{subst:!}}}}{{subst:#if:{{{below|}}} |внизу = {{{below}}} {{subst:!}}}}{{subst:#if:{{{belowstyle|}}}|стиль_внизу = {{{belowstyle}}} }} }}|template=Карточка/импортёр|are_params=1 }}</includeonly><noinclude>{{doc}}</noinclude> 29a99ea8472f8d4050034a77d3570f625e60bf07 Шаблон:(! 10 254 669 668 2024-08-26T15:44:28Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <includeonly>{|</includeonly><noinclude><nowiki>{|</nowiki>{{Doc}} </noinclude> fc286c1b614a7c93a17dd6f17f52dba12b86e363 Шаблон:!) 10 255 671 670 2024-08-26T15:44:28Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki |}<noinclude>{{Doc}} </noinclude> c1895c0eccb60664bc4f2bd850d909b3c65739c3 Шаблон:Pipe 10 256 673 672 2024-08-26T15:44:34Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki &#124;<noinclude> {{doc}} </noinclude> 7161a16776c0ed421759a1aee1e8f465d7b8949a Шаблон:Импортёр шаблона-карточки 10 257 675 674 2024-08-26T15:44:35Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{ombox | text = Это [[Википедия:Обёртки шаблонов-карточек#Импортёры|импортёр]], преобразовывающий включение шаблона {{t|{{{3|{{PAGENAME}}}}}|lang={{#if:{{{2|}}}|{{{2|}}}|en}}}} во включение шаблона {{t|{{{1}}}}}. Для его использования выполните [[Википедия:Механизм шаблонов#Подстановка|подстановку]]: скопируйте код включения шаблона {{t|{{{3|{{PAGENAME}}}}}|lang={{#if:{{{2|}}}|{{{2|}}}|en}}}} из статьи другого раздела в статью русской Википедии, замените название шаблона: {{(!}} width="80%" align="center" {{!}}- {{!}} width="45%" {{!}} <p<includeonly>r</includeonly>e>{{{{{3|{{PAGENAME}}}}} {{pipe}} ... = ... }}</p<includeonly>r</includeonly>e> {{!}} &nbsp;→&nbsp; {{!}} <p<includeonly>r</includeonly>e>{{subst:{{#if:{{{1|}}}|{{{1|}}}/импортёр|{{PAGENAME}}}} {{pipe}} ... = ... }}</p<includeonly>r</includeonly>e> {{!)}} и сохраните страницу. Пожалуйста, не забывайте после этого переводить значения параметров, если и где необходимо. }}<includeonly>{{no-doc|nocat={{{nocat|}}}|[[Категория:Импортёры шаблонов-карточек]]}}</includeonly><noinclude>{{doc}}</noinclude> a73640b844d55fb1ba86e8b0f62016e9e86e95a8 Шаблон:Карточка/импортёр/doc 10 258 677 676 2024-08-26T15:44:35Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{docpage}} {{Импортёр шаблона-карточки||en|Infobox}} Этот подстановочный шаблон используется для быстрого перевода параметров карточек из английской Википедии. Если у вас не получается добиться подстановкой данного шаблона правильного переноса шаблона-карточки из английского раздела, пожалуйста, обратитесь [[Википедия:Форум/Технический|на технический форум]] за помощью в адаптации. 456ee3241716a284eec9a77f6d33a397f9f6181c Модуль:Карточка 828 83 678 141 2024-08-26T16:04:53Z DuOfOrl 5 Scribunto text/plain local p = {} local args = {} local origArgs = {} local root local empty_row_categories = {} local category_in_empty_row_pattern = '%[%[%s*[Cc][Aa][Tt][Ee][Gg][Oo][Rr][Yy]%s*:[^]]*]]' local has_rows = false local lists = { plainlist_t = { patterns = { '^plainlist$', '%splainlist$', '^plainlist%s', '%splainlist%s' }, found = false, styles = 'Plainlist/styles.css' }, hlist_t = { patterns = { '^hlist$', '%shlist$', '^hlist%s', '%shlist%s' }, found = false, styles = 'Hlist/styles.css' } } local function has_list_class(args_to_check) for _, list in pairs(lists) do if not list.found then for _, arg in pairs(args_to_check) do for _, pattern in ipairs(list.patterns) do if mw.ustring.find(arg or '', pattern) then list.found = true break end end if list.found then break end end end end end local function fixChildBoxes(sval, tt) local function notempty( s ) return s and s:match( '%S' ) end if notempty(sval) then local marker = '<span class=special_infobox_marker>' local s = sval -- start moving templatestyles and categories inside of table rows local slast = '' while slast ~= s do slast = s s = mw.ustring.gsub(s, '(</[Tt][Rr]%s*>%s*)(%[%[%s*[Cc][Aa][Tt][Ee][Gg][Oo][Rr][Yy]%s*:[^]]*%]%])', '%2%1') s = mw.ustring.gsub(s, '(</[Tt][Rr]%s*>%s*)(\127[^\127]*UNIQ%-%-templatestyles%-%x+%-QINU[^\127]*\127)', '%2%1') end -- end moving templatestyles and categories inside of table rows s = mw.ustring.gsub(s, '(<%s*[Tt][Rr])', marker .. '%1') s = mw.ustring.gsub(s, '(</[Tt][Rr]%s*>)', '%1' .. marker) if s:match(marker) then s = mw.ustring.gsub(s, marker .. '%s*' .. marker, '') s = mw.ustring.gsub(s, '([\r\n]|-[^\r\n]*[\r\n])%s*' .. marker, '%1') s = mw.ustring.gsub(s, marker .. '%s*([\r\n]|-)', '%1') s = mw.ustring.gsub(s, '(</[Cc][Aa][Pp][Tt][Ii][Oo][Nn]%s*>%s*)' .. marker, '%1') s = mw.ustring.gsub(s, '(<%s*[Tt][Aa][Bb][Ll][Ee][^<>]*>%s*)' .. marker, '%1') s = mw.ustring.gsub(s, '^(%{|[^\r\n]*[\r\n]%s*)' .. marker, '%1') s = mw.ustring.gsub(s, '([\r\n]%{|[^\r\n]*[\r\n]%s*)' .. marker, '%1') s = mw.ustring.gsub(s, marker .. '(%s*</[Tt][Aa][Bb][Ll][Ee]%s*>)', '%1') s = mw.ustring.gsub(s, marker .. '(%s*\n|%})', '%1') end if s:match(marker) then local subcells = mw.text.split(s, marker) s = '' for k = 1, #subcells do if k == 1 then s = s .. subcells[k] .. '</' .. tt .. '></tr>' elseif k == #subcells then local rowstyle = ' style="display:none"' if notempty(subcells[k]) then rowstyle = '' end s = s .. '<tr' .. rowstyle ..'><' .. tt .. ' colspan=2>\n' .. subcells[k] elseif notempty(subcells[k]) then if (k % 2) == 0 then s = s .. subcells[k] else s = s .. '<tr><' .. tt .. ' colspan=2>\n' .. subcells[k] .. '</' .. tt .. '></tr>' end end end end -- the next two lines add a newline at the end of lists for the PHP parser -- [[Special:Diff/849054481]] -- remove when [[:phab:T191516]] is fixed or OBE s = mw.ustring.gsub(s, '([\r\n][%*#;:][^\r\n]*)$', '%1\n') s = mw.ustring.gsub(s, '^([%*#;:][^\r\n]*)$', '%1\n') s = mw.ustring.gsub(s, '^([%*#;:])', '\n%1') s = mw.ustring.gsub(s, '^(%{%|)', '\n%1') return s else return sval end end -- Cleans empty tables local function cleanInfobox() root = tostring(root) if has_rows == false then root = mw.ustring.gsub(root, '<table[^<>]*>%s*</table>', '') end end -- Returns the union of the values of two tables, as a sequence. local function union(t1, t2) local vals = {} for k, v in pairs(t1) do vals[v] = true end for k, v in pairs(t2) do vals[v] = true end local ret = {} for k, v in pairs(vals) do table.insert(ret, k) end return ret end -- Returns a table containing the numbers of the arguments that exist -- for the specified prefix. For example, if the prefix was 'data', and -- 'data1', 'data2', and 'data5' exist, it would return {1, 2, 5}. local function getArgNums(prefix) local nums = {} for k, v in pairs(args) do local num = tostring(k):match('^' .. prefix .. '([1-9]%d*)$') if num then table.insert(nums, tonumber(num)) end end table.sort(nums) return nums end -- Adds a row to the infobox, with either a header cell -- or a label/data cell combination. local function addRow(rowArgs) if rowArgs.header and rowArgs.header ~= '_BLANK_' then has_rows = true has_list_class({ rowArgs.rowclass, rowArgs.class, args.headerclass }) root :tag('tr') :addClass(rowArgs.rowclass) :cssText(rowArgs.rowstyle) :tag('th') :attr('colspan', '2') :addClass('infobox-header') :addClass(rowArgs.class) :addClass(args.headerclass) -- @deprecated next; target .infobox-<name> .infobox-header :cssText(args.headerstyle) :cssText(rowArgs.rowcellstyle) :wikitext(fixChildBoxes(rowArgs.header, 'th')) if rowArgs.data then root:wikitext( '[[Category:Pages using infobox templates with ignored data cells]]' ) end elseif rowArgs.data and rowArgs.data:gsub(category_in_empty_row_pattern, ''):match('^%S') then has_rows = true has_list_class({ rowArgs.rowclass, rowArgs.class }) local row = root:tag('tr') row:addClass(rowArgs.rowclass) row:cssText(rowArgs.rowstyle) if rowArgs.label then row :tag('th') :attr('scope', 'row') :addClass('infobox-label') -- @deprecated next; target .infobox-<name> .infobox-label :cssText(args.labelstyle) :cssText(rowArgs.rowcellstyle) :wikitext(rowArgs.label) :done() end local dataCell = row:tag('td') dataCell :attr('colspan', not rowArgs.label and '2' or nil) :addClass(not rowArgs.label and 'infobox-full-data' or 'infobox-data') :addClass(rowArgs.class) -- @deprecated next; target .infobox-<name> .infobox(-full)-data :cssText(rowArgs.datastyle) :cssText(rowArgs.rowcellstyle) :wikitext(fixChildBoxes(rowArgs.data, 'td')) else table.insert(empty_row_categories, rowArgs.data or '') end end local function renderTitle() if not args.title then return end has_rows = true has_list_class({args.titleclass}) root :tag('caption') :addClass('infobox-title') :addClass(args.titleclass) -- @deprecated next; target .infobox-<name> .infobox-title :cssText(args.titlestyle) :wikitext(args.title) end local function renderAboveRow() if not args.above then return end has_rows = true has_list_class({ args.aboveclass }) root :tag('tr') :tag('th') :attr('colspan', '2') :addClass('infobox-above') :addClass(args.aboveclass) -- @deprecated next; target .infobox-<name> .infobox-above :cssText(args.abovestyle) :wikitext(fixChildBoxes(args.above,'th')) end local function renderBelowRow() if not args.below then return end has_rows = true has_list_class({ args.belowclass }) root :tag('tr') :tag('td') :attr('colspan', '2') :addClass('infobox-below') :addClass(args.belowclass) -- @deprecated next; target .infobox-<name> .infobox-below :cssText(args.belowstyle) :wikitext(fixChildBoxes(args.below,'td')) end local function addSubheaderRow(subheaderArgs) if subheaderArgs.data and subheaderArgs.data:gsub(category_in_empty_row_pattern, ''):match('^%S') then has_rows = true has_list_class({ subheaderArgs.rowclass, subheaderArgs.class }) local row = root:tag('tr') row:addClass(subheaderArgs.rowclass) local dataCell = row:tag('td') dataCell :attr('colspan', '2') :addClass('infobox-subheader') :addClass(subheaderArgs.class) :cssText(subheaderArgs.datastyle) :cssText(subheaderArgs.rowcellstyle) :wikitext(fixChildBoxes(subheaderArgs.data, 'td')) else table.insert(empty_row_categories, subheaderArgs.data or '') end end local function renderSubheaders() if args.subheader then args.subheader1 = args.subheader end if args.subheaderrowclass then args.subheaderrowclass1 = args.subheaderrowclass end local subheadernums = getArgNums('subheader') for k, num in ipairs(subheadernums) do addSubheaderRow({ data = args['subheader' .. tostring(num)], -- @deprecated next; target .infobox-<name> .infobox-subheader datastyle = args.subheaderstyle, rowcellstyle = args['subheaderstyle' .. tostring(num)], class = args.subheaderclass, rowclass = args['subheaderrowclass' .. tostring(num)] }) end end local function addImageRow(imageArgs) if imageArgs.data and imageArgs.data:gsub(category_in_empty_row_pattern, ''):match('^%S') then has_rows = true has_list_class({ imageArgs.rowclass, imageArgs.class }) local row = root:tag('tr') row:addClass(imageArgs.rowclass) local dataCell = row:tag('td') dataCell :attr('colspan', '2') :addClass('infobox-image') :addClass(imageArgs.class) :cssText(imageArgs.datastyle) :wikitext(fixChildBoxes(imageArgs.data, 'td')) else table.insert(empty_row_categories, imageArgs.data or '') end end local function renderImages() if args.image then args.image1 = args.image end if args.caption then args.caption1 = args.caption end local imagenums = getArgNums('image') for k, num in ipairs(imagenums) do local caption = args['caption' .. tostring(num)] local data = mw.html.create():wikitext(args['image' .. tostring(num)]) if caption then data :tag('div') :addClass('infobox-caption') -- @deprecated next; target .infobox-<name> .infobox-caption :cssText(args.captionstyle) :wikitext(caption) end addImageRow({ data = tostring(data), -- @deprecated next; target .infobox-<name> .infobox-image datastyle = args.imagestyle, class = args.imageclass, rowclass = args['imagerowclass' .. tostring(num)] }) end end -- When autoheaders are turned on, preprocesses the rows local function preprocessRows() if not args.autoheaders then return end local rownums = union(getArgNums('header'), getArgNums('data')) table.sort(rownums) local lastheader for k, num in ipairs(rownums) do if args['header' .. tostring(num)] then if lastheader then args['header' .. tostring(lastheader)] = nil end lastheader = num elseif args['data' .. tostring(num)] and args['data' .. tostring(num)]:gsub( category_in_empty_row_pattern, '' ):match('^%S') then local data = args['data' .. tostring(num)] if data:gsub(category_in_empty_row_pattern, ''):match('%S') then lastheader = nil end end end if lastheader then args['header' .. tostring(lastheader)] = nil end end -- Gets the union of the header and data argument numbers, -- and renders them all in order local function renderRows() local rownums = union(getArgNums('header'), getArgNums('data')) table.sort(rownums) for k, num in ipairs(rownums) do addRow({ header = args['header' .. tostring(num)], label = args['label' .. tostring(num)], data = args['data' .. tostring(num)], datastyle = args.datastyle, class = args['class' .. tostring(num)], rowclass = args['rowclass' .. tostring(num)], -- @deprecated next; target .infobox-<name> rowclass rowstyle = args['rowstyle' .. tostring(num)], rowcellstyle = args['rowcellstyle' .. tostring(num)] }) end end local function renderNavBar() if not args.name then return end has_rows = true root :tag('tr') :tag('td') :attr('colspan', '2') :addClass('infobox-navbar') :wikitext(require('Module:Navbar')._navbar{ args.name, mini = 1, }) end local function renderItalicTitle() local italicTitle = args['italic title'] and mw.ustring.lower(args['italic title']) if italicTitle == '' or italicTitle == 'force' or italicTitle == 'yes' then root:wikitext(require('Module:Italic title')._main({})) end end -- Categories in otherwise empty rows are collected in empty_row_categories. -- This function adds them to the module output. It is not affected by -- args.decat because this module should not prevent module-external categories -- from rendering. local function renderEmptyRowCategories() for _, s in ipairs(empty_row_categories) do root:wikitext(s) end end -- Render tracking categories. args.decat == turns off tracking categories. local function renderTrackingCategories() if args.decat == 'yes' then return end if args.child == 'yes' then if args.title then root:wikitext( '[[Category:Pages using embedded infobox templates with the title parameter]]' ) end elseif #(getArgNums('data')) == 0 and mw.title.getCurrentTitle().namespace == 0 then root:wikitext('[[Category:Articles using infobox templates with no data rows]]') end end --[=[ Loads the templatestyles for the infobox. TODO: FINISH loading base templatestyles here rather than in MediaWiki:Common.css. There are 4-5000 pages with 'raw' infobox tables. See [[Mediawiki_talk:Common.css/to_do#Infobox]] and/or come help :). When we do this we should clean up the inline CSS below too. Will have to do some bizarre conversion category like with sidebar. ]=] local function loadTemplateStyles() local frame = mw.getCurrentFrame() local hlist_templatestyles = '' if lists.hlist_t.found then hlist_templatestyles = frame:extensionTag{ name = 'templatestyles', args = { src = lists.hlist_t.styles } } end local plainlist_templatestyles = '' if lists.plainlist_t.found then plainlist_templatestyles = frame:extensionTag{ name = 'templatestyles', args = { src = lists.plainlist_t.styles } } end -- See function description local base_templatestyles = frame:extensionTag{ name = 'templatestyles', args = { src = 'Module:Infobox/styles.css' } } local templatestyles = '' if args['templatestyles'] then templatestyles = frame:extensionTag{ name = 'templatestyles', args = { src = args['templatestyles'] } } end local child_templatestyles = '' if args['child templatestyles'] then child_templatestyles = frame:extensionTag{ name = 'templatestyles', args = { src = args['child templatestyles'] } } end local grandchild_templatestyles = '' if args['grandchild templatestyles'] then grandchild_templatestyles = frame:extensionTag{ name = 'templatestyles', args = { src = args['grandchild templatestyles'] } } end return table.concat({ -- hlist -> plainlist -> base is best-effort to preserve old Common.css ordering. -- this ordering is not a guarantee because the rows of interest invoking -- each class may not be on a specific page hlist_templatestyles, plainlist_templatestyles, base_templatestyles, templatestyles, child_templatestyles, grandchild_templatestyles }) end -- common functions between the child and non child cases local function structure_infobox_common() renderSubheaders() renderImages() preprocessRows() renderRows() renderBelowRow() renderNavBar() renderItalicTitle() renderEmptyRowCategories() renderTrackingCategories() cleanInfobox() end -- Specify the overall layout of the infobox, with special settings if the -- infobox is used as a 'child' inside another infobox. local function _infobox() if args.child ~= 'yes' then root = mw.html.create('table') root :addClass(args.subbox == 'yes' and 'infobox-subbox' or 'infobox') :addClass(args.bodyclass) -- @deprecated next; target .infobox-<name> :cssText(args.bodystyle) has_list_class({ args.bodyclass }) renderTitle() renderAboveRow() else root = mw.html.create() root :wikitext(args.title) end structure_infobox_common() return loadTemplateStyles() .. root end -- If the argument exists and isn't blank, add it to the argument table. -- Blank arguments are treated as nil to match the behaviour of ParserFunctions. local function preprocessSingleArg(argName) if origArgs[argName] and origArgs[argName] ~= '' then args[argName] = origArgs[argName] end end -- Assign the parameters with the given prefixes to the args table, in order, in -- batches of the step size specified. This is to prevent references etc. from -- appearing in the wrong order. The prefixTable should be an array containing -- tables, each of which has two possible fields, a "prefix" string and a -- "depend" table. The function always parses parameters containing the "prefix" -- string, but only parses parameters in the "depend" table if the prefix -- parameter is present and non-blank. local function preprocessArgs(prefixTable, step) if type(prefixTable) ~= 'table' then error("Non-table value detected for the prefix table", 2) end if type(step) ~= 'number' then error("Invalid step value detected", 2) end -- Get arguments without a number suffix, and check for bad input. for i,v in ipairs(prefixTable) do if type(v) ~= 'table' or type(v.prefix) ~= "string" or (v.depend and type(v.depend) ~= 'table') then error('Invalid input detected to preprocessArgs prefix table', 2) end preprocessSingleArg(v.prefix) -- Only parse the depend parameter if the prefix parameter is present -- and not blank. if args[v.prefix] and v.depend then for j, dependValue in ipairs(v.depend) do if type(dependValue) ~= 'string' then error('Invalid "depend" parameter value detected in preprocessArgs') end preprocessSingleArg(dependValue) end end end -- Get arguments with number suffixes. local a = 1 -- Counter variable. local moreArgumentsExist = true while moreArgumentsExist == true do moreArgumentsExist = false for i = a, a + step - 1 do for j,v in ipairs(prefixTable) do local prefixArgName = v.prefix .. tostring(i) if origArgs[prefixArgName] then -- Do another loop if any arguments are found, even blank ones. moreArgumentsExist = true preprocessSingleArg(prefixArgName) end -- Process the depend table if the prefix argument is present -- and not blank, or we are processing "prefix1" and "prefix" is -- present and not blank, and if the depend table is present. if v.depend and (args[prefixArgName] or (i == 1 and args[v.prefix])) then for j,dependValue in ipairs(v.depend) do local dependArgName = dependValue .. tostring(i) preprocessSingleArg(dependArgName) end end end end a = a + step end end -- Parse the data parameters in the same order that the old {{infobox}} did, so -- that references etc. will display in the expected places. Parameters that -- depend on another parameter are only processed if that parameter is present, -- to avoid phantom references appearing in article reference lists. local function parseDataParameters() preprocessSingleArg('autoheaders') preprocessSingleArg('child') preprocessSingleArg('bodyclass') preprocessSingleArg('subbox') preprocessSingleArg('bodystyle') preprocessSingleArg('title') preprocessSingleArg('titleclass') preprocessSingleArg('titlestyle') preprocessSingleArg('above') preprocessSingleArg('aboveclass') preprocessSingleArg('abovestyle') preprocessArgs({ {prefix = 'subheader', depend = {'subheaderstyle', 'subheaderrowclass'}} }, 10) preprocessSingleArg('subheaderstyle') preprocessSingleArg('subheaderclass') preprocessArgs({ {prefix = 'image', depend = {'caption', 'imagerowclass'}} }, 10) preprocessSingleArg('captionstyle') preprocessSingleArg('imagestyle') preprocessSingleArg('imageclass') preprocessArgs({ {prefix = 'header'}, {prefix = 'data', depend = {'label'}}, {prefix = 'rowclass'}, {prefix = 'rowstyle'}, {prefix = 'rowcellstyle'}, {prefix = 'class'} }, 50) preprocessSingleArg('headerclass') preprocessSingleArg('headerstyle') preprocessSingleArg('labelstyle') preprocessSingleArg('datastyle') preprocessSingleArg('below') preprocessSingleArg('belowclass') preprocessSingleArg('belowstyle') preprocessSingleArg('name') -- different behaviour for italics if blank or absent args['italic title'] = origArgs['italic title'] preprocessSingleArg('decat') preprocessSingleArg('templatestyles') preprocessSingleArg('child templatestyles') preprocessSingleArg('grandchild templatestyles') end -- If called via #invoke, use the args passed into the invoking template. -- Otherwise, for testing purposes, assume args are being passed directly in. function p.infobox(frame) if frame == mw.getCurrentFrame() then origArgs = frame:getParent().args else origArgs = frame end parseDataParameters() return _infobox() end -- For calling via #invoke within a template function p.infoboxTemplate(frame) origArgs = {} for k,v in pairs(frame.args) do origArgs[k] = mw.text.trim(v) end parseDataParameters() return _infobox() end return p 0ddb7e5c8426d67cd589b710efb9912ddfb67fea Шаблон:Политик 10 259 680 679 2024-08-26T16:45:34Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{Карточка |имя = Политик |from = {{{from|}}} |стиль_меток = min-width:9em; |вверху = {{карточка/имя|{{{имя|{{{Имя|}}}}}}|from={{{from|}}}}} |вверху2 = {{карточка/оригинал имени|{{{оригинал имени|{{{Оригинал имени|}}}}}}|from={{{from|}}}}} |изображение = {{wikidata|p18|{{{изображение|{{{Изображение|}}}}}}|size={{{ширина|{{{Ширина|}}}}}}|caption={{{описание изображения|{{{Описание изображения|}}}}}}|from={{{from|}}}}} |метка1 = Имя при рождении |текст1 = {{{имя при рождении|{{{Имя при рождении|}}}}}} |метка2 = Псевдонимы |текст2 = {{{псевдонимы|{{{Псевдонимы|}}}}}} |метка3 = Дата&nbsp;рождения |текст3 = {{wikidata/p569|{{{дата рождения|{{{Дата рождения|}}}}}}|{{{дата смерти|{{{Дата смерти|}}}}}}|from={{{from|}}}}} |метка4 = Место рождения |текст4 = {{{место рождения|{{{Место рождения|}}}}}} |викиданные4 = p19 |метка5 = Дата&nbsp;смерти |текст5 = {{wikidata/p570|{{{дата смерти|{{{Дата смерти|}}}}}}|{{{дата рождения|{{{Дата рождения|}}}}}}|from={{{from|}}}}} |метка6 = Место смерти |текст6 = {{{место смерти|{{{Место смерти|}}}}}} |викиданные6 = p20 |метка7 = Гражданство |текст7 = {{{страна|{{{гражданство|{{{подданство|{{{Гражданство|}}}}}}}}}}}} |викиданные7 = p27 |метка8 = Род&nbsp;деятельности |текст8 = {{{род деятельности|{{{Род деятельности|}}}}}} |викиданные8 = p106 |метка9 = Образование |текст9 = {{{образование|{{{альма-матер|{{{Образование|}}}}}}}}} |викиданные9 = p69 |метка10 = Учёная степень |текст10 = {{{учёная степень|{{{Учёная степень|}}}}}} |викиданные10 = p512 |метка11 = Учёное звание |текст11 = {{{учёное звание|{{{Учёное звание|}}}}}} |метка12 = Вероисповедание |текст12 = {{{вероисповедание|{{{Вероисповедание|}}}}}} |викиданные12 = p140 |метка13 = Партия |текст13 = {{{партия|{{{Партия|}}}}}} |викиданные13 = p102 |метка14 = Основные идеи |текст14 = {{{основные идеи|{{{Основные идеи|}}}}}} |викиданные14 = p1142 |метка15 = Отец |текст15 = {{{отец|{{{Отец|}}}}}} |викиданные15 = p22 |метка16 = Мать |текст16 = {{{мать|{{{Мать|}}}}}} |викиданные16 = p25 |метка17 = {{wikidata gender switch||Супруг|Супруга|Супруг(а)}} |текст17 = {{wikidata|p26|{{#if: {{{супруга|{{{Супруга|}}}}}} | {{{супруга|{{{Супруга|}}}}}} | {{{супруг|{{{Супруг|}}}}}} }}}} |метка18 = Дети |текст18 = {{{дети|{{{Дети|}}}}}} |викиданные18 = p40 |метка19 = Награды |текст19 = {{{награды|{{{награды и премии|{{{Награды|}}}}}}}}} |викиданные19 = p166 |метка20 = Автограф |текст20 = {{wikidata|p109|{{{автограф|{{{Автограф|}}}}}}|size={{#if:{{{ширина автографа|{{{Ширина автографа|}}}}}}|{{{ширина автографа|{{{Ширина автографа}}}}}}|143x143}}|alt=Автограф|from={{{from|}}}}} |внизу = {{wikidata|p856|{{{сайт|{{{Сайт|}}}}}}|from={{{from|}}}}} |внизу2 = {{карточка/Викисклад|{{{викисклад|{{{Викисклад|}}}}}}|from={{{from|}}}}} }}<!-- -->{{#if:{{NAMESPACE}}{{{nocat|}}}||<!-- -->[[Категория:Персоналии по алфавиту]]<!-- -->[[Категория:Политики по алфавиту]]<!-- -->{{#invoke:Wikidata/category|categorizeIfNoParams}}<!-- -->{{#invoke:CategoryForProfession|mainFunction}}<!-- -->{{Сортировка: по изображениям|{{{изображение|{{{Изображение|}}}}}}|from={{{from|}}}|nocat={{{nocat|}}}|default-type=человек|default-occupation=политик}}<!-- -->}}<!-- -->{{#invoke:check for unknown parameters|check | unknown = {{#if: {{NAMESPACE}} || [[Категория:Страницы с неизвестными параметрами шаблона Политик|_VALUE_]] }} | ignoreblank = | preview = <span class="error">Неизвестный параметр «_VALUE_» шаблона Политик</span> | showblankpositional= 1 |from|nocat|Автограф|Вероисповедание|Викисклад|Гражданство|Дата рождения|Дата смерти|Дети|Изображение|Имя|Имя при рождении|Мать|Место рождения|Место смерти|Награды|Образование|Описание изображения|Оригинал имени|Основные идеи|Отец|Партия|Псевдонимы|Род деятельности|Сайт|Супруг|Супруга|Учёная степень|Учёное звание|Ширина|Ширина автографа<!-- -->|автограф|вероисповедание|викисклад|гражданство|дата рождения|дата смерти|дети|изображение|имя|имя при рождении|мать|место рождения|место смерти|награды|образование|описание изображения|оригинал имени|основные идеи|отец|партия|псевдонимы|род деятельности|сайт|супруг|супруга|учёная степень|учёное звание|ширина|ширина автографа |альма-матер|страна|подданство|награды и премии }}<!-- --><noinclude>{{doc}}</noinclude> 6e99fb4d8a3ec44096ba8d60276e31241c0d8f65 Шаблон:Хх 10 260 682 681 2024-08-26T16:45:41Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki [[<noinclude> {{doc}} <!-- Пожалуйста, добавляйте категории и интервики на страницу документации! --></noinclude> c18d284eaccac8b03717d7977a4bd795d3ad7f3c Шаблон:Wikidata 10 261 684 683 2024-08-26T16:45:42Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <includeonly>{{#invoke:Wikidata|formatProperty|property={{{1|}}}|value={{{2|}}}}}</includeonly><noinclude>{{doc}}</noinclude> 9d3d422eca39504b018df6ec0bb047392a7aba7e Модуль:Wikidata 828 262 686 685 2024-08-26T16:45:44Z DuOfOrl 5 1 версия импортирована Scribunto text/plain ---settings, may differ from project to project local fileDefaultSize = '267x400px' local outputReferences = true local writingSystemElementId = 'Q8209' local langElementId = 'Q7737' ---Ссылки на используемые модули, которые потребуются в 99% случаев загрузки страниц (чтобы иметь на виду при переименовании) local moduleSources = require( 'Module:Sources' ) local WDS = require( 'Module:WikidataSelectors' ) ---Константы ---@type string local CONTENT_LANGUAGE_CODE = mw.language.getContentLanguage():getCode() local p = {} local g_config, g_frame local formatDatavalue, formatEntityId, formatRefs, formatSnak, formatStatement, formatStatementDefault, getSourcingCircumstances, getPropertyParams ---@param obj table ---@param target table ---@param skipEmpty boolean | nil ---@return table local function copyTo( obj, target, skipEmpty ) for key, val in pairs( obj ) do if skipEmpty ~= true or ( val ~= nil and val ~= '' ) then target[ key ] = val end end return target end ---@param prev number | nil ---@param next number | nil ---@return number | nil local function min( prev, next ) if prev == nil or prev > next then return next end return prev end ---@param prev number | nil ---@param next number | nil ---@return number | nil local function max( prev, next ) if prev == nil or prev < next then return next end return prev end ---@param section string ---@param code string ---@return any | nil local function getConfig( section, code ) if g_config == nil then g_config = require( 'Module:Wikidata/config' ) end if not g_config then g_config = {} end if not section then return g_config end if not code then return g_config[ section ] or {} end if not g_config[ section ] then return nil end return g_config[ section ][ code ] end ---@param code string ---@param sortKey string | nil ---@return string local function getCategoryByCode( code, sortKey ) local value = getConfig( 'categories', code ) if not value or value == '' then return '' end if sortKey ~= nil then return '[[Category:' .. value .. '|' .. sortKey .. ']]'; -- экранировать? else return '[[Category:' .. value .. ']]' end end ---@param isoStr string | table ---@return table | nil local function splitISO8601( isoStr ) if 'table' == type( isoStr ) then if isoStr.args and isoStr.args[ 1 ] then isoStr = '' .. isoStr.args[ 1 ] else return 'unknown argument type: ' .. type( isoStr ) .. ': ' .. table.tostring( isoStr ) end end local Y, M, D = ( function( str ) local pattern = "(%-?%d+)%-(%d+)%-(%d+)T" local _Y, _M, _D = mw.ustring.match( str, pattern ) return tonumber( _Y ), tonumber( _M ), tonumber( _D ) end )( isoStr ) local h, m, s = ( function( str ) local pattern = "T(%d+):(%d+):(%d+)%Z" local _H, _M, _S = mw.ustring.match( str, pattern ) return tonumber( _H ), tonumber( _M ), tonumber( _S ) end )( isoStr ) local oh, om = ( function( str ) if str:sub(-1) == "Z" then -- ends with Z, Zulu time return 0, 0 end -- matches ±hh:mm, ±hhmm or ±hh; else returns nils local pattern = "([-+])(%d%d):?(%d?%d?)$" local sign, oh, om = mw.ustring.match( str, pattern ) sign, oh, om = sign or "+", oh or "00", om or "00" return tonumber( sign .. oh ), tonumber( sign .. om ) end )( isoStr ) return { year=Y, month=M, day=D, hour=( h + oh ), min=( m + om ), sec=s } end ---Внутренняя функции для получения границ временного диапазона ---@param time string ---@param precision number ---@return table | nil function p._parseTimeBoundaries( time, precision ) local s = splitISO8601( time ) if not s then return nil end if precision >= 0 and precision <= 8 then local powers = { 1000000000 , 100000000, 10000000, 1000000, 100000, 10000, 1000, 100, 10 } local power = powers[ precision + 1 ] local left = s.year - ( s.year % power ) return { tonumber( os.time( { year=left, month=1, day=1, hour=0, min=0, sec=0 } ) ) * 1000, tonumber( os.time( { year=left + power - 1, month=12, day=31, hour=29, min=59, sec=58 } ) ) * 1000 + 1999 } end if precision == 9 then return { tonumber( os.time( { year=s.year, month=1, day=1, hour=0, min=0, sec=0} )) * 1000, tonumber( os.time( { year=s.year, month=12, day=31, hour=23, min=59, sec=58} )) * 1000 + 1999 } end if precision == 10 then local lastDays = { 31, 28.25, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } local lastDay = lastDays[ s.month ] return { tonumber( os.time( { year=s.year, month=s.month, day=1, hour=0, min=0, sec=0 } ) ) * 1000, tonumber( os.time( { year=s.year, month=s.month, day=lastDay, hour=23, min=59, sec=58 } ) ) * 1000 + 1999 } end if precision == 11 then return { tonumber( os.time( { year=s.year, month=s.month, day=s.day, hour=0, min=0, sec=0 } ) ) * 1000, tonumber( os.time( { year=s.year, month=s.month, day=s.day, hour=23, min=59, sec=58 } ) ) * 1000 + 1999 } end if precision == 12 then return { tonumber( os.time( { year=s.year, month=s.month, day=s.day, hour=s.hour, min=0, sec=0 } ) ) * 1000, tonumber( os.time( { year=s.year, month=s.month, day=s.day, hour=s.hour, min=59, sec=58 } ) ) * 1000 + 1999 } end if precision == 13 then return { tonumber( os.time( { year=s.year, month=s.month, day=s.day, hour=s.hour, min=s.min, sec=0 } ) ) * 1000, tonumber( os.time( { year=s.year, month=s.month, day=s.day, hour=s.hour, min=s.min, sec=58 } ) ) * 1000 + 1999 } end if precision == 14 then local t = tonumber( os.time( { year=s.year, month=s.month, day=s.day, hour=s.hour, min=s.min, sec=0 } ) ) return { t * 1000, t * 1000 + 999 } end error( 'Unsupported precision: ' .. precision ) end ---Внутренняя функция для получения числового значения времени из snak'а ---@param table snak ---@return number | nil function p._parseTimeFromSnak( snak ) if snak and snak.datavalue and snak.datavalue.value and snak.datavalue.value.time then local timeData = splitISO8601( tostring( snak.datavalue.value.time ) ) timeData.month = math.max( timeData.month, 1 ) timeData.day = math.max( timeData.day, 1 ) return tonumber( os.time( timeData ) ) * 1000 end return nil end ---Функция для формирования категории на основе wikidata/config ---@param options table ---@param entityId string ---@return string local function extractCategory( options, entityId ) if not entityId or not options.category or options.nocat then return '' end if type( entityId ) ~= 'string' then entityId = entityId.id end local claims = WDS.load( entityId, options.category ) if not claims then return '' end for _, claim in pairs( claims ) do if claim and claim.mainsnak and claim.mainsnak.datavalue and claim.mainsnak.datavalue.type == 'wikibase-entityid' then local catEntityId = claim.mainsnak.datavalue.value.id local wbStatus, catSiteLink = pcall( mw.wikibase.getSitelink, catEntityId ) if wbStatus and catSiteLink then return '[[' .. catSiteLink .. ']]' end end end return '' end ---Преобразует строку в булевое значение ---@param valueToParse string ---@return boolean Преобразованное значение, если его удалось распознать, или defaultValue во всех остальных случаях local function toBoolean( valueToParse, defaultValue ) if valueToParse ~= nil then if valueToParse == false or valueToParse == '' or valueToParse == 'false' or valueToParse == '0' then return false end return true end return defaultValue end ---Обрачивает отформатированное значение в инлайновый или блочный тег. ---@param value string value ---@param attributes table of attributes ---@return string HTML tag with value local function wrapValue( value, attributes ) local tagName = 'span' local spacer = '' if string.match( value, '\n' ) or string.match( value, '<t[dhr][ >]' ) or string.match( value, '<div[ >]' ) or string.find( value, 'UNIQ%-%-imagemap' ) then tagName = 'div' spacer = '\n' end local attrString = '' for key, val in pairs( attributes or {} ) do local _key = mw.text.trim( key ) local _value = mw.text.encode( mw.text.trim( val ) ) attrString = attrString .. _key .. '="' .. _value .. '" ' end return '<' .. tagName .. ' ' .. attrString .. '>' .. spacer .. value .. '</' .. tagName .. '>' end ---Wraps formatted snak value into HTML tag with attributes. ---@param value string value of snak ---@param hash string ---@param attributes table of extra attributes ---@return string HTML tag with value local function wrapSnak( value, hash, attributes ) local newAttributes = mw.clone( attributes or {} ) newAttributes[ 'class' ] = ( newAttributes[ 'class' ] or '' ) .. ' wikidata-snak' if hash then newAttributes[ 'data-wikidata-hash'] = hash else newAttributes[ 'class' ] = newAttributes[ 'class' ] .. ' wikidata-main-snak' end return wrapValue( value, newAttributes ) end ---Wraps formatted statement value into HTML tag with attributes. ---@param value string value of statement ---@param propertyId string PID of property ---@param claimId string ID of claim or nil for local value ---@param attributes table of extra attributes ---@return string HTML tag with value local function wrapStatement( value, propertyId, claimId, attributes ) local newAttributes = mw.clone( attributes or {} ) newAttributes[ 'class' ] = newAttributes[ 'class' ] or '' newAttributes[ 'data-wikidata-property-id' ] = string.upper( propertyId ) if claimId then newAttributes[ 'class' ] = newAttributes[ 'class' ] .. ' wikidata-claim' newAttributes[ 'data-wikidata-claim-id' ] = claimId else newAttributes[ 'class' ] = newAttributes[ 'class' ] .. ' no-wikidata' end return wrapValue( value, newAttributes ) end ---Wraps formatted qualifier's statement value into HTML tag with attributes. ---@param value string value of qualifier's statement ---@param qualifierId string PID of qualifier ---@param attributes table of extra attributes ---@return string HTML tag with value local function wrapQualifier( value, qualifierId, attributes ) local newAttributes = mw.clone( attributes or {} ) newAttributes[ 'data-wikidata-qualifier-id' ] = string.upper( qualifierId ) return wrapValue( value, newAttributes ) end ---Функция для получения сущности (еntity) для текущей страницы ---Подробнее о сущностях см. d:Wikidata:Glossary/ru ---@param id string Идентификатор (типа P18, Q42) ---@return table Таблица, элементы которой индексируются с нуля local function getEntityFromId( id ) local entity local wbStatus if id then wbStatus, entity = pcall( mw.wikibase.getEntity, id ) else wbStatus, entity = pcall( mw.wikibase.getEntity ) end return entity end ---Внутренняя функция для формирования сообщения об ошибке ---@param key string Ключ элемента в таблице config.errors (например entity-not-found) ---@return void local function throwError( key ) error( getConfig( 'errors', key ) ) end ---Функция для получения идентификатора сущностей ---@param value table ---@return string local function getEntityIdFromValue( value ) local prefix = '' if value[ 'entity-type' ] == 'item' then prefix = 'Q' elseif value[ 'entity-type' ] == 'property' then prefix = 'P' else throwError( 'unknown-entity-type' ) end return prefix .. value[ 'numeric-id' ] end ---Проверка на наличие специализированной функции в опциях ---@param options table ---@param prefix string ---@return function local function getUserFunction( options, prefix, defaultFunction ) -- проверка на указание специализированных обработчиков в параметрах, -- переданных при вызове if options[ prefix .. '-module' ] or options[ prefix .. '-function' ] then -- проверка на пустые строки в параметрах или их отсутствие if not options[ prefix .. '-module' ] or not options[ prefix .. '-function' ] then throwError( 'unknown-' .. prefix .. '-module' ) end -- динамическая загруза модуля с обработчиком указанным в параметре local formatter = require( 'Module:' .. options[ prefix .. '-module' ] ) if formatter == nil then throwError( prefix .. '-module-not-found' ) end local fun = formatter[ options[ prefix .. '-function' ] ] if fun == nil then throwError( prefix .. '-function-not-found' ) end return fun end return defaultFunction end ---Выбирает свойства по property id, дополнительно фильтруя их по рангу ---@param context table ---@param options table ---@param propertySelector string ---@return table | nil local function selectClaims( context, options, propertySelector ) if not context then error( 'context not specified' ); end if not options then error( 'options not specified' ); end if not options.entityId then error( 'options.entity is missing' ); end if not propertySelector then error( 'propertySelector not specified' ); end local result = WDS.load( options.entityId, propertySelector ) if not result or #result == 0 then return nil end if options.limit and options.limit ~= '' and options.limit ~= '-' then local limit = tonumber( options.limit, 10 ) while #result > limit do table.remove( result ) end end return result end ---Функция для получения значения свойства элемента в заданный момент времени. ---@param entityId string ---@param boundaries table Временные границы ---@param propertyIds table<string> ---@param selectors table<string> ---@return table Таблица соответствующих значений свойства local function getPropertyInBoundaries( context, entityId, boundaries, propertyIds, selectors ) if type( entityId ) ~= 'string' then error( 'type of entityId argument expected string, but was ' .. type(entityId)); end local results = {} if not propertyIds or #propertyIds == 0 then return results end for i, propertyId in ipairs( propertyIds ) do local selector if selectors ~= nil then selector = selectors[ i ] or selectors[ propertyId ] or propertyId else selector = propertyId end local fakeAllClaims = {} fakeAllClaims[ propertyId ] = mw.wikibase.getAllStatements( entityId, propertyId ) local filteredClaims = WDS.filter( fakeAllClaims, selector .. '[rank:preferred, rank:normal]' ) if filteredClaims then for _, claim in pairs( filteredClaims ) do if not boundaries then if not claim.qualifiers or not claim.qualifiers.P582 then table.insert( results, claim.mainsnak ) end else local startBoundaries = p.getTimeBoundariesFromQualifier( context.frame, context, claim, 'P580' ) local endBoundaries = p.getTimeBoundariesFromQualifier( context.frame, context, claim, 'P582' ) if ( startBoundaries == nil or startBoundaries[ 1 ] <= boundaries[ 1 ] ) and ( endBoundaries == nil or endBoundaries[ 1 ] >= boundaries[ 2 ] ) then table.insert( results, claim.mainsnak ) end end end end if #results > 0 then break end end return results end ---@param context table ---@param propertyId string ---@return table | nil function p.getTimeBoundariesFromProperty( context, propertyId ) local dateClaims = WDS.filter( context.entity.claims, propertyId ) if not dateClaims or #dateClaims == 0 then return nil; end -- only support exact date so far, but need improvment local left = nil local right = nil for _, claim in pairs( dateClaims ) do if not claim.mainsnak then return nil end local boundaries = context.parseTimeBoundariesFromSnak( claim.mainsnak ) if not boundaries then return nil end left = min( left, boundaries[ 1 ] ) right = max( right, boundaries[ 2 ] ) end if not left or not right then return nil end return { left, right } end ---@param context table ---@param propertyIds table<string> ---@return table | nil function p.getTimeBoundariesFromProperties( context, propertyIds ) for _, propertyId in ipairs( propertyIds ) do local result = p.getTimeBoundariesFromProperty( context, propertyId ); if result then return result end end return nil end ---@param context table ---@param statement table ---@param qualifierId string ---@return table | nil function p.getTimeBoundariesFromQualifier( _, context, statement, qualifierId ) -- only support exact date so far, but need improvement local left, right if statement.qualifiers and statement.qualifiers[ qualifierId ] then for _, qualifier in pairs( statement.qualifiers[ qualifierId ] ) do local boundaries = context.parseTimeBoundariesFromSnak( qualifier ) if not boundaries then return nil end left = min( left, boundaries[ 1 ] ) right = max( right, boundaries[ 2 ] ) end end if not left or not right then return nil end return { left, right } end ---@param _ table ---@param context table ---@param statement table ---@param qualifierIds table<string> ---@return table | nil function p.getTimeBoundariesFromQualifiers( _, context, statement, qualifierIds ) if not qualifierIds then qualifierIds = { 'P582', 'P580', 'P585' } end for _, qualifierId in pairs( qualifierIds ) do local result = p.getTimeBoundariesFromQualifier( _, context, statement, qualifierId ) if result then return result end end return nil end ---@type table<string> local getLabelWithLang_DEFAULT_PROPERTIES = { 'P1813', 'P1448', 'P1705' } ---@type table<string> local getLabelWithLang_DEFAULT_SELECTORS = { 'P1813[language:' .. CONTENT_LANGUAGE_CODE .. '][!P282,P282:' .. writingSystemElementId .. '][!P3831,P3831:Q105690470]', 'P1448[language:' .. CONTENT_LANGUAGE_CODE .. '][!P282,P282:' .. writingSystemElementId .. '][!P3831,P3831:Q105690470]', 'P1705[language:' .. CONTENT_LANGUAGE_CODE .. '][!P282,P282:' .. writingSystemElementId .. '][!P3831,P3831:Q105690470]' } ---Функция для получения метки элемента в заданный момент времени. ---@param context table ---@param options table ---@param entityId string ---@param boundaries table ---@param propertyIds table ---@param selectors table<string> ---@return string, string Текстовая метка элемента, язык метки local function getLabelWithLang( context, options, entityId, boundaries, propertyIds, selectors ) if type( entityId ) ~= 'string' then error( 'type of entityId argument expected string, but was ' .. type( entityId ) ); end if not entityId then return nil end local langCode = CONTENT_LANGUAGE_CODE -- name from label local label if options.text and options.text ~= '' then label = options.text else if not propertyIds then propertyIds = getLabelWithLang_DEFAULT_PROPERTIES selectors = getLabelWithLang_DEFAULT_SELECTORS end -- name from properties local results = getPropertyInBoundaries( context, entityId, boundaries, propertyIds, selectors ) for _, result in pairs( results ) do if result.datavalue and result.datavalue.value then if result.datavalue.type == 'monolingualtext' and result.datavalue.value.text then label = result.datavalue.value.text langCode = result.datavalue.value.language break elseif result.datavalue.type == 'string' then label = result.datavalue.value break end end end if not label then label, langCode = mw.wikibase.getLabelWithLang( entityId ) if not langCode then return nil end end end return label, langCode end ---@param context table ---@param options table ---@return string local function formatPropertyDefault( context, options ) if not context then error( 'context not specified' ); end if not options then error( 'options not specified' ); end if not options.entityId then error( 'options.entityId missing' ); end local claims if options.property then -- TODO: Почему тут может не быть property? if options.rank then -- передать настройки ранга из конфига claims = context.selectClaims( options, options.property .. options.rank ) else claims = context.selectClaims( options, options.property ) end end if claims == nil then return '' --TODO error? end -- Обход всех заявлений утверждения и с накоплением оформленных предпочтительных -- заявлений в таблице local formattedClaims = {} for _, claim in pairs( claims ) do local formattedStatement = context.formatStatement( options, claim ) -- здесь может вернуться либо оформленный текст заявления, либо строка ошибки, либо nil if formattedStatement and formattedStatement ~= '' then if not options.plain then formattedStatement = context.wrapStatement( formattedStatement, options.property, claim.id ) end table.insert( formattedClaims, formattedStatement ) end end -- создание текстовой строки со списком оформленых заявлений из таблицы local out = mw.text.listToText( formattedClaims, options.separator, options.conjunction ) if out ~= '' then if options.before then out = options.before .. out end if options.after then out = out .. options.after end end return out end ---Create context ---@param initOptions table ---@return table | nil local function initContext( initOptions ) local context = { entityId = initOptions.entityId, entity = initOptions.entity, extractCategory = extractCategory, formatSnak = formatSnak, formatPropertyDefault = formatPropertyDefault, formatStatementDefault = formatStatementDefault, getPropertyInBoundaries = getPropertyInBoundaries, getTimeBoundariesFromProperty = p.getTimeBoundariesFromProperty, getTimeBoundariesFromProperties = p.getTimeBoundariesFromProperties, getTimeBoundariesFromQualifier = p.getTimeBoundariesFromQualifier, getTimeBoundariesFromQualifiers = p.getTimeBoundariesFromQualifiers, parseTimeFromSnak = p._parseTimeFromSnak, getLabelWithLang = getLabelWithLang, wrapSnak = wrapSnak, wrapStatement = wrapStatement, wrapQualifier = wrapQualifier, } context.cloneOptions = function( options ) local entity = options.entity options.entity = nil local newOptions = mw.clone( options ) options.entity = entity newOptions.entity = entity newOptions.frame = options.frame; -- На склонированном фрейме frame:expandTemplate() return newOptions end context.formatProperty = function( options ) local func = getUserFunction( options, 'property', context.formatPropertyDefault ) return func( context, options ) end context.formatStatement = function( options, statement ) return formatStatement( context, options, statement ) end context.formatSnak = function( options, snak, circumstances ) return formatSnak( context, options, snak, circumstances ) end context.formatRefs = function( options, statement ) return formatRefs( context, options, statement ) end context.parseTimeBoundariesFromSnak = function( snak ) if snak and snak.datavalue and snak.datavalue.value and snak.datavalue.value.time and snak.datavalue.value.precision then return p._parseTimeBoundaries( snak.datavalue.value.time, snak.datavalue.value.precision ) end return nil end context.getSourcingCircumstances = function( statement ) return getSourcingCircumstances( statement ) end context.selectClaims = function( options, propertyId ) return selectClaims( context, options, propertyId ) end return context end ---Функция для оформления утверждений (statement) ---Подробнее о утверждениях см. d:Wikidata:Glossary/ru ---@param options table ---@return string Formatted wikitext. local function formatProperty( options ) -- Получение сущности по идентификатору local entity = getEntityFromId( options.entityId ) if not entity then return -- throwError( 'entity-not-found' ) end -- проверка на присутсвие у сущности заявлений (claim) -- подробнее о заявлениях см. d:Викиданные:Глоссарий if not entity.claims then return '' --TODO error? end -- improve options options.frame = g_frame options.entity = entity options.extends = function( self, newOptions ) return copyTo( newOptions, copyTo( self, {} ) ) end if options.i18n then options.i18n = copyTo( options.i18n, copyTo( getConfig( 'i18n' ), {} ) ) else options.i18n = getConfig( 'i18n' ) end local context = initContext( options ) return context.formatProperty( options ) end ---Функция для оформления одного утверждения (statement) ---@param context table ---@param options table ---@param statement table ---@return string Formatted wikitext. function formatStatement( context, options, statement ) if not statement then error( 'statement is not specified or nil' ) end if not statement.type or statement.type ~= 'statement' then throwError( 'unknown-claim-type' ) end local functionToCall = getUserFunction( options, 'claim', context.formatStatementDefault ) return functionToCall( context, options, statement ) end ---@param statement table ---@return table function getSourcingCircumstances( statement ) if not statement then error( 'statement is not specified' ) end local circumstances = {} if statement.qualifiers and statement.qualifiers.P1480 then for _, qualifier in pairs( statement.qualifiers.P1480 ) do if qualifier and qualifier.datavalue and qualifier.datavalue.type == 'wikibase-entityid' and qualifier.datavalue.value and qualifier.datavalue.value[ 'entity-type'] == 'item' then table.insert( circumstances, qualifier.datavalue.value.id ) end end end return circumstances end ---Функция для оформления одного утверждения (statement) ---@param context table Context. ---@param options table Parameters. ---@param statement table ---@return string Formatted wikitext. function formatStatementDefault( context, options, statement ) if not context then error( 'context is not specified' ) end if not options then error( 'options is not specified' ) end if not statement then error( 'statement is not specified' ) end local circumstances = context.getSourcingCircumstances( statement ) options.qualifiers = statement.qualifiers local result = context.formatSnak( options, statement.mainsnak, circumstances ) if options.qualifier and statement.qualifiers and statement.qualifiers[ options.qualifier ] then local qualifierConfig = getPropertyParams( options.qualifier, nil, {} ) if options.i18n then qualifierConfig.i18n = options.i18n end if qualifierConfig.datatype == 'time' then qualifierConfig.nolinks = true end local qualifierValues = {} for _, qualifierSnak in pairs( statement.qualifiers[ options.qualifier ] ) do local snakValue = context.formatSnak( qualifierConfig, qualifierSnak ) if snakValue and snakValue ~= '' then table.insert( qualifierValues, snakValue ) end end if result and result ~= '' and #qualifierValues then if qualifierConfig.invisible then result = result .. table.concat( qualifierValues, ', ' ) else result = result .. ' (' .. table.concat( qualifierValues, ', ' ) .. ')' end end end if result and result ~= '' and options.references then result = result .. context.formatRefs( options, statement ) end return result end ---Функция для оформления части утверждения (snak) ---Подробнее о snak см. d:Викиданные:Глоссарий ---@param context table Context. ---@param options table Parameters. ---@param snak table ---@param circumstances table ---@return string Formatted wikitext. function formatSnak( context, options, snak, circumstances ) circumstances = circumstances or {} local result if snak.snaktype == 'somevalue' then if options[ 'somevalue' ] and options[ 'somevalue' ] ~= '' then result = options[ 'somevalue' ] else result = options.i18n[ 'somevalue' ] end elseif snak.snaktype == 'novalue' then if options[ 'novalue' ] and options[ 'novalue' ] ~= '' then result = options[ 'novalue' ] else result = options.i18n[ 'novalue' ] end elseif snak.snaktype == 'value' then result = formatDatavalue( context, options, snak.datavalue, snak.datatype ) for _, item in pairs( circumstances ) do if options.i18n[ item ] then result = options.i18n[ item ] .. result end end else throwError( 'unknown-snak-type' ) end if not result or result == '' then return nil end if options.plain then return result end return context.wrapSnak( result, snak.hash ) end ---Функция для оформления объектов-значений с географическими координатами ---@param value string Raw value. ---@param options table Parameters. ---@return string Formatted string. local function formatGlobeCoordinate( value, options ) -- проверка на требование в параметрах вызова на возврат сырого значения if options[ 'subvalue' ] == 'latitude' then -- широты return value[ 'latitude' ] elseif options[ 'subvalue' ] == 'longitude' then -- долготы return value[ 'longitude' ] elseif options[ 'nocoord' ] and options[ 'nocoord' ] ~= '' then -- если передан параметр nocoord, то не выводить координаты -- обычно это делается при использовании нескольких карточек на странице return '' else -- в противном случае формируются параметры для вызова шаблона {{coord}} -- нужно дописать в документации шаблона, что он отсюда вызывается, и что -- любое изменние его парамеров должно быть согласовано с кодом тут local coordModule = require( 'Module:Coordinates' ) local globe = options.globe or '' if globe == '' and value[ 'globe' ] then local globes = require( 'Module:Wikidata/Globes' ) globe = globes[ value[ 'globe' ] ] or '' end local display = 'inline' if options.display and options.display ~= '' then display = options.display elseif ( options.property:upper() == 'P625' ) then display = 'title' end local format = options.format or '' if format == '' then format = 'dms' if value[ 'precision' ] then local precision = value[ 'precision' ] * 60 if precision >= 60 then format = 'd' elseif precision >= 1 then format = 'dm' end end end g_frame.args = { tostring( value[ 'latitude' ] ), tostring( value[ 'longitude' ] ), globe = globe, type = options.type and options.type or '', scale = options.scale and options.scale or '', display = display, format = format, } return coordModule.coord(g_frame) end end ---Функция для оформления объектов-значений с файлами с Викисклада ---@param value string Raw value. ---@param options table Parameters. ---@return string Formatted string. local function formatCommonsMedia( value, options ) local image = value local caption = '' if options[ 'caption' ] and options[ 'caption' ] ~= '' then caption = options[ 'caption' ] end if caption ~= '' then caption = wrapQualifier( caption, 'P2096', { class = 'media-caption', style = 'display:block' } ) end if not string.find( value, '[%[%]%{%}]' ) and not string.find( value, 'UNIQ%-%-imagemap' ) then -- если в value не содержится викикод или imagemap, то викифицируем имя файла -- ищем слово imagemap в строке, потому что вставляется плейсхолдер: [[phab:T28213]] image = '[[File:' .. value .. '|frameless' if options[ 'border' ] and options[ 'border' ] ~= '' then image = image .. '|border' end local size = options[ 'size' ] if size and size ~= '' then -- TODO: check localized pixel names too if not string.match( size, 'px$' ) then size = size .. 'px' end else size = fileDefaultSize end image = image .. '|' .. size if options[ 'alt' ] and options[ 'alt' ] ~= '' then image = image .. '|alt=' .. options[ 'alt' ] end if caption ~= '' then image = image .. '|' .. caption end image = image .. ']]' if caption ~= '' then image = image .. '<br>' .. caption end else image = image .. caption .. getCategoryByCode( 'media-contains-markup' ) end return image end ---Function for render math formulas ---@param value string Value. ---@param options table Parameters. ---@return string Formatted string. local function formatMath( value, options ) return options.frame:extensionTag{ name = 'math', content = value } end ---Функция для оформления внешних идентификаторов ---@param value string ---@param options table ---@return string local function formatExternalId( value, options ) local formatter = options.formatter local propertyId = options.property:upper() if not formatter or formatter == '' then local isGoodFormat = false local wbStatus, formatRegexStatements = pcall( mw.wikibase.getBestStatements, propertyId, 'P1793' ) if wbStatus and formatRegexStatements then for _, statement in pairs( formatRegexStatements ) do if statement.mainsnak.snaktype == 'value' then local pattern = mw.ustring.gsub( statement.mainsnak.datavalue.value, '\\', '%' ) pattern = mw.ustring.gsub( pattern, '{%d+,?%d*}', '+' ) if ( string.find( pattern, '|' ) or string.find( pattern, '%)%?' ) or mw.ustring.match( value, '^' .. pattern .. '$' ) ~= nil ) then isGoodFormat = true break end end end end if isGoodFormat then local formatterStatements wbStatus, formatterStatements = pcall( mw.wikibase.getBestStatements, propertyId, 'P1630' ) if wbStatus and formatterStatements then for _, statement in pairs( formatterStatements ) do if statement.mainsnak.snaktype == 'value' then formatter = statement.mainsnak.datavalue.value break end end end end end if formatter and formatter ~= '' then local encodedValue = mw.ustring.gsub( value, '%%', '%%%%' ) -- ломается, если подставить внутрь другого mw.ustring.gsub local link = mw.ustring.gsub( mw.ustring.gsub( formatter, '$1', encodedValue ), '.', { [ ' ' ] = '%20', [ '+' ] = '%2b', [ '[' ] = '%5B', [ ']' ] = '%5D' } ) local title = options.title if not title or title == '' then title = '$1' end title = mw.ustring.gsub( mw.ustring.gsub( title, '$1', encodedValue ), '.', { [ '[' ] = '(', [ ']' ] = ')' } ) return '[' .. link .. ' ' .. title .. ']' end return value end ---Функция для оформления числовых значений ---@param value table Объект-значение ---@param options table Таблица параметров ---@return string Оформленный текст local function formatQuantity( value, options ) -- диапазон значений local amount = string.gsub( value.amount, '^%+', '' ) local lang = mw.language.getContentLanguage() local langCode = lang:getCode() local function formatNum( number, sigfig ) local multiplier = '' if options.countByThousands then local powers = options.i18n.thousandPowers local pos = 1 while math.abs( number ) >= 1000 and pos < #powers do number = number / 1000 pos = pos + 1 end multiplier = powers[ pos ] if math.abs( number ) >= 100 then sigfig = sigfig or 0 elseif math.abs( number ) >= 10 then sigfig = sigfig or 1 else sigfig = sigfig or 2 end else sigfig = sigfig or 12 -- округление до 12 знаков после запятой, на 13-м возникает ошибка в точности end local iMultiplier = 10^sigfig number = math.floor( number * iMultiplier + 0.5 ) / iMultiplier return string.gsub( lang:formatNum( number ), '^-', '−' ) .. multiplier end local out = formatNum( tonumber( amount ) ) if value.upperBound then local diff = tonumber( value.upperBound ) - tonumber( amount ) if diff > 0 then -- временная провека, пока у большинства значений не будет убрано ±0 -- Пробуем понять до какого знака округлять local integer, dot, decimals, _ = value.upperBound:match( '^+?-?(%d*)(%.?)(%d*)(.*)' ) local precision if dot == '' then precision = -integer:match( '0*$' ):len() else precision = #decimals end local bound = formatNum( diff, precision ) if string.match( bound, 'E%-(%d+)' ) then -- если в экспоненциальном формате local digits = tonumber( string.match( bound, 'E%-(%d+)' ) ) - 2 bound = formatNum( diff * 10 ^ digits, precision ) bound = string.sub( bound, 0, 2 ) .. string.rep( '0', digits ) .. string.sub( bound, -string.len( bound ) + 2 ) end out = out .. ' ± ' .. bound end end if options.unit and options.unit ~= '' then if options.unit ~= '-' then out = out .. ' ' .. options.unit end elseif value.unit and string.match( value.unit, 'http://www.wikidata.org/entity/' ) then local unitEntityId = string.gsub( value.unit, 'http://www.wikidata.org/entity/', '' ) if unitEntityId ~= 'undefined' then local wbStatus, unitEntity = pcall( mw.wikibase.getEntity, unitEntityId ) if wbStatus == true and unitEntity then if unitEntity.claims.P2370 and unitEntity.claims.P2370[ 1 ].mainsnak.snaktype == 'value' and not value.upperBound and options.siConversion == true then local conversionToSiUnit = string.gsub( unitEntity.claims.P2370[ 1 ].mainsnak.datavalue.value.amount, '^%+', '' ) if math.floor( math.log10( conversionToSiUnit ) ) ~= math.log10( conversionToSiUnit ) then -- Если не степени десятки (переводить сантиметры в метры не надо!) local outValue = tonumber( amount ) * conversionToSiUnit if outValue > 0 then -- Пробуем понять до какого знака округлять local integer, dot, decimals, _ = amount:match( '^(%d*)(%.?)(%d*)(.*)' ) local precision if dot == '' then precision = -integer:match( '0*$' ):len() else precision = #decimals end local adjust = math.log10( math.abs( conversionToSiUnit ) ) + math.log10( 2 ) local minPrecision = 1 - math.floor( math.log10( outValue ) + 2e-14 ) out = formatNum( outValue, math.max( math.floor( precision + adjust ), minPrecision ) ) else out = formatNum( outValue, 0 ) end unitEntityId = string.gsub( unitEntity.claims.P2370[ 1 ].mainsnak.datavalue.value.unit, 'http://www.wikidata.org/entity/', '' ) wbStatus, unitEntity = pcall( mw.wikibase.getEntity, unitEntityId ) end end local label = getLabelWithLang( context, options, unitEntity.id, nil, { "P5061", "P558", "P558" }, { 'P5061[language:' .. langCode .. ']', 'P558[P282:' .. writingSystemElementId .. ', P407:' .. langElementId .. ']', 'P558[!P282][!P407]' } ) out = out .. ' ' .. label end end end return out end ---Функция для оформления URL ---@param context table ---@param options table ---@param value string local function formatUrlValue( context, options, value ) if not options.length or options.length == '' then options.length = 25 end local moduleUrl = require( 'Module:URL' ) return moduleUrl.formatUrlSingle( context, options, value ) end local DATATYPE_CACHE = {} ---Get property datatype by ID. ---@param propertyId string Property ID, e.g. 'P123'. ---@return string Property datatype, e.g. 'commonsMedia', 'time' or 'url'. local function getPropertyDatatype( propertyId ) if not propertyId or not string.match( propertyId, '^P%d+$' ) then return nil end local cached = DATATYPE_CACHE[ propertyId ] if cached ~= nil then return cached end local wbStatus, propertyEntity = pcall( mw.wikibase.getEntity, propertyId ) if wbStatus ~= true or not propertyEntity then return nil end mw.log("Loaded datatype " .. propertyEntity.datatype .. " of " .. propertyId .. ' from wikidata, consider passing datatype argument to formatProperty call or to Wikidata/config' ) DATATYPE_CACHE[ propertyId ] = propertyEntity.datatype return propertyEntity.datatype end ---@param datavalue table ---@return function local function getPlainValueFunction( datavalue, _ ) if datavalue.type == 'wikibase-entityid' then return function( _, _, value ) return getEntityIdFromValue( value ) end elseif datavalue.type == 'string' then return function( _, _, value ) return value end elseif datavalue.type == 'monolingualtext' then return function( _, _, value ) return value.text end elseif datavalue.type == 'globecoordinate' then return function( _, _, value ) return value.latitude .. ',' .. value.longitude end elseif datavalue.type == 'quantity' then return function( _, _, value ) return value.amount end elseif datavalue.type == 'time' then return function( _, _, value ) return value.time end end throwError( 'unknown-datavalue-type' ) end ---@param datavalue table ---@param datatype string ---@return function local function getDefaultValueFunction( datavalue, datatype ) -- вызов обработчиков по умолчанию для известных типов значений if datavalue.type == 'wikibase-entityid' then -- Entity ID return function( context, options, value ) return formatEntityId( context, options, getEntityIdFromValue( value ) ) end elseif datavalue.type == 'string' then -- String if datatype and datatype == 'commonsMedia' then -- Media return function( _, options, value ) return formatCommonsMedia( value, options ) end elseif datatype and datatype == 'external-id' then -- External ID return function( _, options, value ) return formatExternalId( value, options ) end elseif datatype and datatype == 'math' then -- Math formula return function( _, options, value ) return formatMath( value, options ) end elseif datatype and datatype == 'url' then -- URL return formatUrlValue end return function( _, _, value ) return value end elseif datavalue.type == 'monolingualtext' then -- моноязычный текст (строка с указанием языка) return function( _, options, value ) if options.monolingualLangTemplate == 'lang' then if value.language == CONTENT_LANGUAGE_CODE then return value.text end return options.frame:expandTemplate{ title = 'lang-' .. value.language, args = { value.text } } elseif options.monolingualLangTemplate == 'ref' then return '<span class="lang" lang="' .. value.language .. '">' .. value.text .. '</span>' .. options.frame:expandTemplate{ title = 'ref-' .. value.language } else return '<span class="lang" lang="' .. value.language .. '">' .. value.text .. '</span>' end end elseif datavalue.type == 'globecoordinate' then -- географические координаты return function( _, options, value ) return formatGlobeCoordinate( value, options ) end elseif datavalue.type == 'quantity' then return function( _, options, value ) return formatQuantity( value, options ) end elseif datavalue.type == 'time' then return function( context, options, value ) local moduleDate = require( 'Module:Wikidata/date' ) return moduleDate.formatDate( context, options, value ) end end -- во всех стальных случаях возвращаем ошибку throwError( 'unknown-datavalue-type' ) end ---Функция для оформления значений (value) ---Подробнее о значениях см. d:Wikidata:Glossary/ru ---@param context table ---@param options table ---@param datavalue table ---@param datatype string ---@return string Оформленный текст function formatDatavalue( context, options, datavalue, datatype ) if not context then error( 'context not specified' ); end if not options then error( 'options not specified' ); end if not datavalue then error( 'datavalue not specified' ); end if not datavalue.value then error( 'datavalue.value is missing' ); end -- проверка на указание специализированных обработчиков в параметрах, -- переданных при вызове if options.plain then context.formatValueDefault = getPlainValueFunction( datavalue, datatype ) else context.formatValueDefault = getDefaultValueFunction( datavalue, datatype ) end local functionToCall = getUserFunction( options, 'value', context.formatValueDefault ) return functionToCall( context, options, datavalue.value ) end local DEFAULT_BOUNDARIES = { os.time() * 1000, os.time() * 1000} ---Функция для оформления идентификатора сущности ---@param context table ---@param options table ---@param entityId string ---@return string Оформленный текст function formatEntityId( context, options, entityId ) -- получение локализованного названия local boundaries if options.qualifiers then boundaries = p.getTimeBoundariesFromQualifiers( context.frame, context, { qualifiers = options.qualifiers } ) end if not boundaries then boundaries = DEFAULT_BOUNDARIES end local label, labelLanguageCode = getLabelWithLang( context, options, entityId, boundaries ) -- определение соответствующей показываемому элементу категории local category = context.extractCategory( options, { id = entityId } ) -- получение ссылки по идентификатору local link = mw.wikibase.sitelink( entityId ) if link then -- ссылка на категорию, а не добавление страницы в неё if mw.ustring.match( link, '^' .. mw.site.namespaces[ 14 ].name .. ':' ) then link = ':' .. link end if label and not options.rawArticle then if labelLanguageCode ~= CONTENT_LANGUAGE_CODE then label = '<span lang="' .. label .. '">' .. label .. '</span>' end local a = '[[' .. link .. '|' .. label .. ']]' if CONTENT_LANGUAGE_CODE ~= labelLanguageCode and 'mul' ~= labelLanguageCode then a = a .. getCategoryByCode( 'links-to-entities-with-missing-local-language-label' ) end return a .. category else return '[[' .. link .. ']]' .. category end end if label then -- TODO: возможно, лучше просто mw.wikibase.getLabel(entityId) -- красная ссылка -- TODO: разобраться, почему не всегда есть options.frame local moduleRedLink = require( 'Module:Wikidata/redLink' ) local title = mw.title.new( label ) if title and not title.exists and options.frame then local rawLabel = mw.wikibase.getLabel(entityId) or label -- без |text= и boundaries; or label - костыль local redLink = moduleRedLink.formatRedLinkWithInfobox(rawLabel, label, entityId) if CONTENT_LANGUAGE_CODE ~= labelLanguageCode and 'mul' ~= labelLanguageCode then redLink = '<span lang="' .. labelLanguageCode .. '">' .. redLink .. '</span>' .. getCategoryByCode( 'links-to-entities-with-missing-local-language-label' ) end return redLink .. category end -- TODO: перенести до проверки на существование статьи local addWdLink = false if ( not options.format or options.format ~= 'text' ) and entityId ~= 'Q6581072' and entityId ~= 'Q6581097' -- TODO: переписать на format=text then addWdLink = true end -- одноимённая статья уже существует - выводится текст и ссылка на ВД return moduleRedLink.formatText(label, entityId, addWdLink) .. category end -- сообщение об отсутвии локализованного названия -- not good, but better than nothing return '[[:d:' .. entityId .. '|' .. entityId .. ']]<span style="border-bottom: 1px dotted; cursor: help; white-space: nowrap" title="В Викиданных нет русской подписи к элементу. Вы можете помочь, указав русский вариант подписи.">?</span>' .. getCategoryByCode( 'links-to-entities-with-missing-label' ) .. category end ---Функция для оформления утверждений (statement) ---Подробнее о утверждениях см. d:Wikidata:Glossary/ru ---@deprecated Use p.formatProperty() instead ---@param frame table ---@return string Строка оформленного текста, предназначенная для отображения в статье function p.formatStatements( frame ) return p.formatProperty( frame ) end ---Получение параметров, которые обычно используются для вывода свойства. ---@param propertyId string ---@param datatype string ---@param params table function getPropertyParams( propertyId, datatype, params ) local config = getConfig() -- Различные уровни настройки параметров, по убыванию приоритета local propertyParams = {} -- 1. Параметры, указанные явно при вызове if params then for key, value in pairs( params ) do if value ~= '' then propertyParams[ key ] = value end end end if toBoolean( propertyParams.plain, false ) then propertyParams.separator = propertyParams.separator or ', ' propertyParams.conjunction = propertyParams.conjunction or ', ' else -- 2. Настройки конкретного параметра if config.properties and config.properties[ propertyId ] then for key, value in pairs( config.properties[ propertyId ] ) do if propertyParams[ key ] == nil then propertyParams[ key ] = value end end end -- 3. Указанный пресет настроек if propertyParams.preset and config.presets and config.presets[ propertyParams.preset ] then for key, value in pairs( config.presets[ propertyParams.preset ] ) do if propertyParams[ key ] == nil then propertyParams[ key ] = value end end end datatype = datatype or params.datatype or propertyParams.datatype or getPropertyDatatype( propertyId ) if propertyParams.datatype == nil then propertyParams.datatype = datatype end -- 4. Настройки для типа данных if datatype and config.datatypes and config.datatypes[ datatype ] then for key, value in pairs( config.datatypes[ datatype ] ) do if propertyParams[ key ] == nil then propertyParams[ key ] = value end end end -- 5. Общие настройки для всех свойств if config.global then for key, value in pairs( config.global ) do if propertyParams[ key ] == nil then propertyParams[ key ] = value end end end end return propertyParams end ---Функция для оформления утверждений (statement) ---Подробнее о утверждениях см. d:Wikidata:Glossary/ru ---@param frame table ---@return string Строка оформленного текста, предназначенная для отображения в статье function p.formatProperty( frame ) local args = copyTo( frame.args, {} ) -- проверка на отсутствие обязательного параметра property if not args.property then throwError( 'property-param-not-provided' ) end local override local propertyId = mw.language.getContentLanguage():ucfirst( string.gsub( args.property, '([^Pp0-9].*)$', function(w) if string.sub( w, 1, 1 ) == '~' then override = w end return '' end ) ) if override then args[ override:match( '[,~]([^=]*)=' ) ] = override:match( '=(.*)' ) args.property = propertyId end -- проброс всех параметров из шаблона {wikidata} и параметра from откуда угодно local p_frame = frame while p_frame do if p_frame:getTitle() == mw.site.namespaces[ 10 ].name .. ':Wikidata' then copyTo( p_frame.args, args, true ) end if p_frame.args and p_frame.args.from and p_frame.args.from ~= '' then args.entityId = p_frame.args.from else args.entityId = mw.wikibase.getEntityIdForCurrentPage() end p_frame = p_frame:getParent() end args = getPropertyParams( propertyId, nil, args ) local datatype = args.datatype -- перевод итоговых значений флагов в true/false и добавление значений -- по умолчанию только в том случае, если они нигде не были указаны ранее args.plain = toBoolean( args.plain, false ) args.nocat = not args.plain and toBoolean( args.nocat, false ) args.references = not args.plain and toBoolean( args.references, true ) -- если значение передано в параметрах вызова то выводим только его if args.value and args.value ~= '' then -- специальное значение для скрытия Викиданных if args.value == '-' then return '' end local value = args.value -- опция, запрещающая оформление значения, поэтому никак не трогаем if args.plain then return value end local context = initContext( args ) -- обработчики по типу значения local wrapperExtraArgs = {} if args[ 'value-module' ] and args[ 'value-function' ] and not string.find( value, '[%[%]%{%}]' ) then local func = getUserFunction( args, 'value' ) value = func( context, args, value ) elseif datatype == 'commonsMedia' then value = formatCommonsMedia( value, args ) elseif datatype == 'external-id' and not string.find( value, '[%[%]%{%}]' ) then wrapperExtraArgs[ 'data-wikidata-external-id' ] = mw.text.killMarkers( value ) value = formatExternalId( value, args ) --elseif datatype == 'math' then -- args.frame = frame -- костыль: в formatMath нужно frame:extensionTag -- value = formatMath( value, args ) elseif datatype == 'url' then value = formatUrlValue( context, args, value ) end -- оборачиваем в тег для JS-функций if string.match( propertyId, '^P%d+$' ) then value = mw.text.trim( value ) -- временная штрафная категория для исправления табличных вставок local allowTables = getPropertyParams( propertyId, nil, {} ).allowTables if not allowTables and string.match( value, '<t[dhr][ >]' ) -- and not string.match( value, '<table[ >]' ) -- and not string.match( value, '^%{%|' ) then value = value .. getCategoryByCode( 'value-contains-table', propertyId ) else value = wrapStatement( value, propertyId, nil, wrapperExtraArgs ) end end return value end -- ability to disable loading Wikidata if args.entityId == '-' then return '' end g_frame = frame -- после проверки всех аргументов -- вызов функции оформления для свойства (набора утверждений) return formatProperty( args ) end ---Функция проверки на присутствие источника в списке нерекомендованных. ---@param snaks table ---@return boolean local function isReferenceDeprecated( snaks ) if not snaks then return false end if snaks.P248 and snaks.P248[ 1 ] and snaks.P248[ 1 ].datavalue and snaks.P248[ 1 ].datavalue.value.id then local entityId = snaks.P248[ 1 ].datavalue.value.id if getConfig( 'deprecatedSources', entityId ) then return true end elseif snaks.P1433 and snaks.P1433[ 1 ] and snaks.P1433[ 1 ].datavalue and snaks.P1433[ 1 ].datavalue.value.id then local entityId = snaks.P1433[ 1 ].datavalue.value.id if getConfig( 'deprecatedSources', entityId ) then return true end end return false end ---Функция оформления ссылок на источники (reference) ---Подробнее о ссылках на источники см. d:Wikidata:Glossary/ru --- ---Экспортируется в качестве зарезервированной точки для вызова из функций-расширения вида claim-module/claim-function через context ---Вызов из других модулей напрямую осуществляться не должен (используйте frame:expandTemplate вместе с одним из специлизированных шаблонов вывода значения свойства). ---@param context table ---@param options table ---@param statement table ---@return string Оформленные примечания для отображения в статье function formatRefs( context, options, statement ) if not context then error( 'context not specified' ); end if not options then error( 'options not specified' ); end if not options.entityId then error( 'options.entityId missing' ); end if not statement then error( 'statement not specified' ); end if not outputReferences then return '' end ---@type string[] local references = {} if statement.references then local hasNotDeprecated = false local displayCount = 0 for _, reference in pairs( statement.references ) do if not isReferenceDeprecated( reference.snaks ) then hasNotDeprecated = true end end for _, reference in pairs( statement.references ) do local display = true if hasNotDeprecated then if isReferenceDeprecated( reference.snaks ) then display = false end end if displayCount >= 2 then if options.entityId and options.property then local propertyId = mw.ustring.match( options.property, '^[Pp][0-9]+' ) -- TODO: обрабатывать не тут, а раньше local moreReferences = '<sup>[[d:' .. options.entityId .. '#' .. string.upper( propertyId ) .. '|[…]]]</sup>' table.insert( references, moreReferences ) end break end if display == true then ---@type string local refText = moduleSources.renderReference( g_frame, options.entityId, reference ) if refText and refText ~= '' then table.insert( references, refText ) displayCount = displayCount + 1 end end end end return table.concat( references ) end return p 4558f762f30c6ebfb9f5333dbd7ebda83c6873f2 Шаблон:Delink 10 263 688 687 2024-08-26T16:45:47Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{<includeonly>safesubst:</includeonly>#invoke:delink|delink}}<noinclude> {{doc}} </noinclude> dbac86e53b946e60d5b6236381e8c31858e79ee5 Модуль:Delink 828 264 690 689 2024-08-26T16:45:47Z DuOfOrl 5 1 версия импортирована Scribunto text/plain -- This module de-links most wikitext. require("strict") local yesno = require("Module:Yesno") local p = {} local getArgs local function delinkReversePipeTrick(s) if s:match("^%[%[|.*[|\n]") then -- Check for newlines or multiple pipes. return s end return s:match("%[%[|(.*)%]%]") end local function delinkPipeTrick(s) -- We need to deal with colons, brackets, and commas, per [[Help:Pipe trick]]. -- First, remove the text before the first colon, if any. if s:match(":") then s = s:match("%[%[.-:(.*)|%]%]") -- If there are no colons, grab all of the text apart from the square brackets and the pipe. else s = s:match("%[%[(.*)|%]%]") end -- Next up, brackets and commas. if s:match("%(.-%)$") then -- Brackets trump commas. s = s:match("(.-) ?%(.-%)$") elseif s:match(",") then -- If there are no brackets, display only the text before the first comma. s = s:match("(.-),.*$") end return s end -- Return wikilink target |wikilinks=target local function getDelinkedTarget(s) local result = s -- Deal with the reverse pipe trick. if result:match("%[%[|") then return delinkReversePipeTrick(result) end result = mw.uri.decode(result, "PATH") -- decode percent-encoded entities. Leave underscores and plus signs. result = mw.text.decode(result, true) -- decode HTML entities. -- Check for bad titles. To do this we need to find the -- title area of the link, i.e. the part before any pipes. local target_area if result:match("|") then -- Find if we're dealing with a piped link. target_area = result:match("^%[%[(.-)|.*%]%]") else target_area = result:match("^%[%[(.-)%]%]") end -- Check for bad characters. if mw.ustring.match(target_area, "[%[%]<>{}%%%c\n]") and mw.ustring.match(target_area, "[%[%]<>{}%%%c\n]") ~= "?" then return s end return target_area end local function getDelinkedLabel(s) local result = s -- Deal with the reverse pipe trick. if result:match("%[%[|") then return delinkReversePipeTrick(result) end result = mw.uri.decode(result, "PATH") -- decode percent-encoded entities. Leave underscores and plus signs. result = mw.text.decode(result, true) -- decode HTML entities. -- Check for bad titles. To do this we need to find the -- title area of the link, i.e. the part before any pipes. local target_area if result:match("|") then -- Find if we're dealing with a piped link. target_area = result:match("^%[%[(.-)|.*%]%]") else target_area = result:match("^%[%[(.-)%]%]") end -- Check for bad characters. if mw.ustring.match(target_area, "[%[%]<>{}%%%c\n]") and mw.ustring.match(target_area, "[%[%]<>{}%%%c\n]") ~= "?" then return s end -- Check for categories, interwikis, and files. local colon_prefix = result:match("%[%[(.-):.*%]%]") or "" -- Get the text before the first colon. local ns = mw.site.namespaces[colon_prefix] -- see if this is a known namespace if mw.language.isKnownLanguageTag(colon_prefix) or (ns and (ns.canonicalName == "File" or ns.canonicalName == "Category")) then return "" end -- Remove the colon if the link is using the [[Help:Colon trick]]. if result:match("%[%[:") then result = "[[" .. result:match("%[%[:(.*%]%])") end -- Deal with links using the [[Help:Pipe trick]]. if mw.ustring.match(result, "^%[%[[^|]*|%]%]") then return delinkPipeTrick(result) end -- Find the display area of the wikilink if result:match("|") then -- Find if we're dealing with a piped link. result = result:match("^%[%[.-|(.+)%]%]") -- Remove new lines from the display of multiline piped links, -- where the pipe is before the first new line. result = result:gsub("\n", "") else result = result:match("^%[%[(.-)%]%]") end return result end local function delinkURL(s) -- Assume we have already delinked internal wikilinks, and that -- we have been passed some text between two square brackets [foo]. -- If the text contains a line break it is not formatted as a URL, regardless of other content. if s:match("\n") then return s end -- Check if the text has a valid URL prefix and at least one valid URL character. local valid_url_prefixes = {"//", "http://", "https://", "ftp://", "gopher://", "mailto:", "news:", "irc://"} local url_prefix for _ ,v in ipairs(valid_url_prefixes) do if mw.ustring.match(s, '^%[' .. v ..'[^"%s].*%]' ) then url_prefix = v break end end -- Get display text if not url_prefix then return s end s = s:match("^%[" .. url_prefix .. "(.*)%]") -- Grab all of the text after the URL prefix and before the final square bracket. s = s:match('^.-(["<> ].*)') or "" -- Grab all of the text after the first URL separator character ("<> ). s = mw.ustring.match(s, "^%s*(%S.*)$") or "" -- If the separating character was a space, trim it off. local s_decoded = mw.text.decode(s, true) if mw.ustring.match(s_decoded, "%c") then return s end return s_decoded end local function delinkLinkClass(text, pattern, delinkFunction) if type(text) ~= "string" then error("Attempt to de-link non-string input.", 2) end if type(pattern) ~= "string" or mw.ustring.sub(pattern, 1, 1) ~= "^" then error('Invalid pattern detected. Patterns must begin with "^".', 2) end -- Iterate over the text string, and replace any matched text. using the -- delink function. We need to iterate character by character rather -- than just use gsub, otherwise nested links aren't detected properly. local result = "" while text ~= "" do -- Replace text using one iteration of gsub. text = mw.ustring.gsub(text, pattern, delinkFunction, 1) -- Append the left-most character to the result string. result = result .. mw.ustring.sub(text, 1, 1) text = mw.ustring.sub(text, 2, -1) end return result end function p._delink(args) local text = args[1] or "" if yesno(args.markers) == true then text = mw.text.killMarkers(text) -- [[Help:Strip markers]] end if yesno(args.refs) == true then -- Remove any [[Help:Strip markers]] representing ref tags. In most situations -- this is not a good idea - only use it if you know what you are doing! text = mw.ustring.gsub(text, "UNIQ%w*%-ref%-%d*%-QINU", "") end if not (yesno(args.comments) == false) then text = text:gsub("<!%-%-.-%-%->", "") -- Remove html comments. end if not (yesno(args.wikilinks) == false) and args.wikilinks ~= "target" then -- De-link wikilinks and return the label portion of the wikilink. text = delinkLinkClass(text, "^%[%[.-%]%]", getDelinkedLabel) elseif args.wikilinks == "target" then -- De-link wikilinks and return the target portions of the wikilink. text = delinkLinkClass(text, "^%[%[.-%]%]", getDelinkedTarget) end if not (yesno(args.urls) == false) then text = delinkLinkClass(text, "^%[.-%]", delinkURL) -- De-link URLs. end if not (yesno(args.whitespace) == false) then -- Replace single new lines with a single space, but leave double new lines -- and new lines only containing spaces or tabs before a second new line. text = mw.ustring.gsub(text, "([^\n \t][ \t]*)\n([ \t]*[^\n \t])", "%1 %2") text = text:gsub("[ \t]+", " ") -- Remove extra tabs and spaces. end return text end function p.delink(frame) if not getArgs then getArgs = require('Module:Arguments').getArgs end return p._delink(getArgs(frame, {wrappers = 'Template:Delink'})) end return p eb6cae0d369f288b0b1600633d9bf7874cefdcbc Модуль:URL 828 265 692 691 2024-08-26T16:45:48Z DuOfOrl 5 1 версия импортирована Scribunto text/plain function startsWith( source, substring ) if mw.ustring.len( substring ) > mw.ustring.len( source ) then return false end return mw.ustring.sub( source, 1, mw.ustring.len( substring ) ) == substring end p = {} function formatUrlImpl( source, title, length ) local scheme, host, path local postfix = '' local arg1, arg2 = source, title local isTestPage = mw.title.getCurrentTitle().prefixedText == 'Модуль:URL' -- Две квадратные скобки подряд — [[вики-ссылка]] вместо [ссылки] — возвращаем вход как есть. if string.find( arg1, "[[", 1, true ) then local result = arg1 if not isTestPage then result = result .. '[[Категория:Википедия:Статьи с вики-ссылкой, переданной в Модуль:URL]]' if arg2 then -- Если есть arg2, а мы распарсить ссылку не смогли, и значит заменить title не сможем корректно, это есть ошибка. result = result .. '[[Категория:Википедия:Статьи с ошибочной работой Модуль:URL]]' end end return result end -- Более одной квадратной скобки — скорее всего, задано более одного URL — тоже возвращаем как есть. if select(2, string.gsub( arg1, "%[", "" )) > 1 then local result = arg1 if not isTestPage then result = result .. '[[Категория:Википедия:Статьи со сложным входом в Модуль:URL]]' if arg2 then -- Если есть arg2, а мы распарсить ссылку не смогли, и значит заменить title не сможем корректно, это есть ошибка. result = result .. '[[Категория:Википедия:Статьи с ошибочной работой Модуль:URL]]' end end return result end source = mw.text.trim( source, "%[%] " ) local titleDelimeterPosition = mw.ustring.find( source, " ", 1 ) if titleDelimeterPosition then if not title or title == "" then title = mw.ustring.sub( source, titleDelimeterPosition + 1 ) local postfixDelimeterPosition = mw.ustring.find( title, "%]", 1 ) if postfixDelimeterPosition then postfix = mw.ustring.sub( title, postfixDelimeterPosition + 1 ) title = mw.ustring.sub( title, 1, postfixDelimeterPosition - 1 ) end end source = mw.ustring.sub( source, 1, titleDelimeterPosition - 1 ) end local hostStartPosition local schemeDelimeterPosition = mw.ustring.find( source, "://", 1, true ) if schemeDelimeterPosition then scheme = mw.ustring.sub( source, 1, schemeDelimeterPosition + 2) hostStartPosition = schemeDelimeterPosition + 3 elseif mw.ustring.find( source, "^//", 1 ) then scheme = "//" hostStartPosition = 3 elseif mw.ustring.find( source, "^mailto:", 1 ) then scheme = "mailto:" hostStartPosition = 8 elseif mw.ustring.find( source, "@", 1 ) then scheme = "mailto:" source = scheme .. source hostStartPosition = 8 else scheme = "http://" source = scheme .. source hostStartPosition = 8 end if title then local finds = mw.ustring.find( arg1, "[", 1, true ) if titleDelimeterPosition and finds and finds > titleDelimeterPosition + 1 then -- Если titleDelimeterPosition промазал мимо скобки и нашел пробел раньше неё, к примеру "a [b c]", -- то свернуть всю нашу хиромантию и выдать первый аргумент без изменений. if arg2 == nil then return arg1 .. (isTestPage and '' or '[[Категория:Википедия:Статьи со сложным входом в Модуль:URL]]') -- Если есть arg2, а мы распарсить ссылку не смогли, и значит заменить title не сможем корректно, это есть ошибка. -- С другой стороны, если arg2 нет, а arg1 очень сложный, то возможно это нормальный ход вещей, -- и на вход в модуль дана уже очень сильно оформленная ссылка. else return arg1 .. (isTestPage and '' or '[[Категория:Википедия:Статьи с ошибочной работой Модуль:URL]]') end end return '[' .. source .. ' ' .. title .. ']' .. postfix end local hostDelimeterPosition = mw.ustring.find( source, "/", hostStartPosition, true ) if hostDelimeterPosition then host = mw.ustring.sub( source, hostStartPosition, hostDelimeterPosition - 1 ) if hostDelimeterPosition == mw.ustring.len( source ) then path = nil else path = mw.ustring.sub( source, hostDelimeterPosition + 1 ) end else host = mw.ustring.sub( source, hostStartPosition ) end -- post-split format options if startsWith( host, 'www.' ) then host = mw.ustring.sub( host, 5 ) end host = mw.language.new( 'en' ):lc( host ) if path and path ~= '' and path ~= '/' then local title = host .. '/' .. path if length and #title > length then title = host .. '/' .. mw.ustring.sub( path, 1, length - #title - 2 ) .. '…' end return '[' .. source .. ' ' .. title .. ']' .. postfix else return '[' .. source .. ' ' .. host .. ']' .. postfix end end function p.formatUrl( frame ) local url = frame.args[1] or '' local title = frame.args[2] or '' local length = frame.args['length'] and tonumber( frame.args['length'] ) url = mw.text.trim( url ) title = mw.text.trim( title ) if url == '' then return nil end if title == '' then title = nil end return formatUrlImpl( url, title, length ) end function p.formatUrlSingle( context, options, url ) url = mw.text.trim( url ) if url == '' then return nil end local title = nil if ( options['text'] and options['text'] ~= '' ) then title = options['text'] end local length = options['length'] and tonumber( options['length'] ) return formatUrlImpl( url, title, length ) end return p a991f879e135a472238c7f589e8d20d92a856d4d Шаблон:!- 10 266 694 693 2024-08-26T16:45:48Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki |-<noinclude> {{doc}} <!-- Пожалуйста, добавляйте категории и интервики на страницу документации! --></noinclude> 4f45a1a9fb060eda6d4afb6850044503035d52bd Шаблон:Карточка/имя 10 267 696 695 2024-08-26T16:45:49Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{#if:{{{1|}}}|{{{1}}}|{{сначала имя|{{PAGENAME}}}}}}<noinclude> {{doc}} </noinclude> c2c97d1196f5c50a2ec1aa866cd4004526a32383 Шаблон:Карточка/оригинал имени 10 268 698 697 2024-08-26T16:45:50Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{wikidata|p1559[language!:ru]|{{{1|}}}|before={{{before|}}}|separator=<br>|conjunction=<br>|monolingualLangTemplate={{{monolingualLangTemplate|lang}}}|from={{{from|}}}}}<!-- -->{{#if:{{NAMESPACE}}||{{#if:{{{1|}}}|{{#ifeq:{{#invoke:String|find|{{{1|}}}|span}}|0|[[Категория:Википедия:Статьи с оригиналом имени без шаблона lang-XX]]}}}}}}<noinclude>{{doc}}</noinclude> a294e3f7f61c5206ca5671b72e21804d7a32fcbc Шаблон:Wikidata/p569 10 269 700 699 2024-08-26T16:45:50Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{#switch:{{{1|}}}|-=|={{#invoke:Wikidata|formatStatements|property=p569|claim-module=Wikidata/date|claim-function=formatDateOfBirthClaim|nocat={{{nocat|}}}{{NAMESPACE}}|suppressAge={{{suppress age|}}}}}|{{#invoke:Infocards|dateOfBirth|{{{1|}}}|{{{2|}}}|suppressAge={{wikidata|P570|plain=true}}{{{suppress age|}}}|nocat={{{nocat|}}}{{NAMESPACE}}}}}}<noinclude>{{doc}}</noinclude> 9643ab18fcd322831b72e38658b58c6b94a914e2 Шаблон:МестоРождения 10 270 702 701 2024-08-26T16:45:51Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <includeonly>{{#if:{{{3|}}}|[[{{{3}}}|{{{1}}}]]|{{#if:{{{1|}}}|[[{{{1}}}]]}}}}{{#if:{{NAMESPACE}}{{{nocat|}}}||{{#if:{{{1|}}}|[[Категория:Персоналии по алфавиту]][[Категория:Родившиеся {{#if:{{{2|}}}|{{{2}}}|в {{#ifeq:{{{1}}}|Ленинград|Санкт-Петербурге|{{Локатив|{{{1}}}}}}}}}]]}}}}</includeonly><noinclude> {{doc}}</noinclude> e03e5faeefe2ece8cfa949e62031800a70ec9773 Шаблон:Wikidata/p570 10 271 704 703 2024-08-26T16:45:51Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{#switch:{{{1|}}}|-=|={{#invoke:Wikidata|formatStatements|property=p570|claim-module=Wikidata/date|claim-function=formatDateOfDeathClaim|nocat={{{nocat|}}}{{NAMESPACE}}}}|{{#invoke:Infocards|dateOfDeath|{{{2|}}}|{{{1|}}}|nocat={{{nocat|}}}{{NAMESPACE}}}}}}<noinclude>{{doc}}</noinclude> a51af6d007d156cfeacb13a0a4a7471da7d4ed22 Шаблон:МестоСмерти 10 272 706 705 2024-08-26T16:45:52Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <includeonly>{{#if:{{{3|}}}|[[{{{3}}}|{{{1}}}]]|{{#if:{{{1|}}}|[[{{{1}}}]]}}}}{{#if:{{NAMESPACE}}||{{#if:{{{1|}}}|[[Категория:Персоналии по алфавиту]][[Категория:Умершие {{#if:{{{2|}}}|{{{2}}}|в {{#ifeq:{{{1}}}|Ленинград|Санкт-Петербурге|{{Локатив|{{{1}}}}}}}}}]]}}}}</includeonly><noinclude> {{doc}}</noinclude> c641a956648523b96cdbeaf3fe0e9c6a4644d4ad Шаблон:Wikidata gender switch 10 273 708 707 2024-08-26T16:45:52Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{#switch: {{wikidata|p21|{{lc:{{delink|{{{1|}}}}}}}|plain=true|from={{{from|}}}}} | 1 | f | fem | female | feminine | ж | жен | женский | женский пол | транс-женщина | Q6581072 | Q1052281 | Q43445 = {{{2}}} | m | male | masculine | м | муж | мужской | мужской пол | транс-мужчина | Q6581097 | Q2449503 | Q44148 = {{{3}}} | #default = {{#if:{{{4|}}}|{{{4}}}|{{{3}}}}} }}<noinclude> {{doc}} </noinclude> 24ccdd5a8702a7028386e9b887d3acf1b5f81c34 Шаблон:Орден Ленина 10 274 710 709 2024-08-26T16:45:53Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{#switch: {{{тип|}}} | воинская часть = [[Файл:Leninorder.svg|40px|link=Орден Ленина|Орден Ленина {{#if: {{{1|}}}|— {{{1}}}}}]]{{#if:{{NAMESPACE}}{{{nocat|}}}||[[Категория:Воинские части, награждённые орденом Ленина]]}} | город = [[Файл:Leninorder.svg|40px|link=Орден Ленина|Орден Ленина {{#if: {{{1|}}}|— {{{1}}}}}]]{{#if:{{NAMESPACE}}{{{nocat|}}}||[[Категория:Города, награждённые орденом Ленина]]}} | регион = [[Файл:Leninorder.svg|40px|link=Орден Ленина|Орден Ленина {{#if: {{{1|}}}|— {{{1}}}}}]]{{#if:{{NAMESPACE}}{{{nocat|}}}||[[Категория:Регионы, награждённые орденом Ленина]]}} | организация = [[Файл:Leninorder.svg|40px|link=Орден Ленина|Орден Ленина {{#if: {{{1|}}}|— {{{1}}}}}]]{{#if:{{NAMESPACE}}{{{nocat|}}}||[[Категория:Организации, награждённые орденом Ленина]]}} | СМИ | сми = [[Файл:Leninorder.svg|40px|link=Орден Ленина|Орден Ленина {{#if: {{{1|}}}|— {{{1}}}}}]]{{#if:{{NAMESPACE}}{{{nocat|}}}||[[Категория:СМИ, награждённые орденом Ленина]]}} | корабль = [[Файл:Leninorder.svg|40px|link=Орден Ленина|Орден Ленина {{#if: {{{1|}}}|— {{{1}}}}}]]{{#if:{{NAMESPACE}}{{{nocat|}}}||[[Категория:Корабли, награждённые орденом Ленина]]}} | [[Файл:SU Order of Lenin ribbon.svg|40px|link=Орден Ленина|Орден Ленина {{#if: {{{1|}}}|— {{{1}}}}}]]{{#if:{{NAMESPACE}}{{{nocat|}}}||[[Категория:Кавалеры ордена Ленина]]}} }}<noinclude> {{doc}} [[Категория:Шаблоны:Награды:СССР|Ленина]] </noinclude> 2abac17c2226c03fa1628e5e5ecd11d7a997a10a Шаблон:Сначала имя 10 275 712 711 2024-08-26T16:45:54Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{safesubst:<noinclude />#ifexpr: {{safesubst:<noinclude />str find|{{safesubst:<noinclude />До символа|{{{1}}}|(}}|,}} = -1 <!-- -->|{{safesubst:<noinclude />До символа|{{{1}}}|(}}<!-- -->|{{safesubst:<noinclude />trim|{{safesubst:<noinclude />После символа|{{safesubst:<noinclude />До символа|{{{1}}}|(}}|,}}}} {{safesubst:<noinclude />До символа|{{safesubst:<noinclude />До символа|{{{1}}}|(}}|,}}<!-- -->}}<noinclude> {{doc}} </noinclude> c3a2e3e13dba0ae595a7c147ca692be2eb183f38 Шаблон:До символа 10 276 714 713 2024-08-26T16:45:54Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{ {{{|safesubst:}}}#invoke:string2|bs|{{{1|}}}|{{{2|}}}|{{{from|1}}}}}<noinclude>{{doc}}</noinclude> 4cd51dc75d5f365cffac57c9577bd2b2f5c7cc3f Модуль:Infocards 828 277 716 715 2024-08-26T16:45:55Z DuOfOrl 5 1 версия импортирована Scribunto text/plain local infocards = {} local calculateAge = true local dateCat = require( 'Module:Infocards/dateCat' ) local moduleDates = require( 'Module:Dates' ) --[[ Helper function that populates the argument list given that user may need to use a mix of named and unnamed parameters. This is relevant because named parameters are not identical to unnamed parameters due to string trimming, and when dealing with strings we sometimes want to either preserve or remove that whitespace depending on the application. ]] function infocards._getParameters( frame_args, arg_list ) local new_args = {} local index = 1 local value for i,arg in ipairs( arg_list ) do value = frame_args[arg] if value == nil then value = frame_args[index] index = index + 1 end new_args[arg] = value end return new_args end function infocards.isBlank( someString ) return someString == nil or mw.ustring.match(someString, '^%s*$') ~= nil end function infocards.isDate ( frame ) local new_args = infocards._getParameters( frame.args, {'s', 't', 'f'} ) local s = new_args['s'] or '' local t = new_args['t'] or '' local f = new_args['f'] or '' local result = infocards.isDateImpl ( s ) if (result) then return t else return f end end function infocards.isDateImpl ( s ) local converted = infocards.convertToDate ( s ) return converted ~= nil end function infocards.dateOfBirth( frame ) local new_args = infocards._getParameters( frame.args, {'dateOfBirth', 'dateOfDeath', 'suppressAge', 'nocat'} ) local dateOfBirth = new_args['dateOfBirth'] or '' local dateOfDeath = new_args['dateOfDeath'] or '' local suppressAge = new_args['suppressAge'] or '' local nocat = new_args['nocat'] or mw.title.getCurrentTitle().nsText return infocards.dateOfBirthImpl( dateOfBirth, dateOfDeath, suppressAge, nocat ) end function infocards.dateOfBirthImpl( dateOfBirth, dateOfDeath, suppressAge, nocat ) local appendToCategory = infocards.isBlank( nocat ) if ( infocards.isBlank( dateOfBirth ) ) then if ( appendToCategory ) then return dateCat.categoryNoBirthDate else return '' end end if ( mw.ustring.match( dateOfBirth, '^%s*неизвестн.%s*$' ) ~= nil or mw.ustring.match( dateOfBirth, '^%s*%?%s*$' ) ~= nil ) then if ( appendToCategory ) then return "''неизвестно''" .. dateCat.categoryUnknownBirthDate else return "''неизвестно''" end end local appendAge = not (suppressAge ~= '' or not calculateAge) and infocards.isBlank( dateOfDeath ) local parsedDate = infocards.convertToDate ( dateOfBirth ) if ( parsedDate == nil ) then --[[ Temporary hack in order to enable export dates to wikidata ]] local bDateStart = '<span class="no-wikidata" data-wikidata-property-id="P569">' local bDateEnd = '</span>' if ( appendToCategory ) then return bDateStart .. dateOfBirth .. bDateEnd .. dateCat.categoryManualWikification else return bDateStart .. dateOfBirth .. bDateEnd end end local result = infocards.formatDateImpl ( parsedDate, 'bday', appendToCategory and 'Родившиеся' or nil ) if ( appendAge ) then -- TODO: месяцы и дни для (нескольких) новорождённых (см. новейшие [[Категория:Родившиеся в ГГГГ году]]) local age = infocards.age ( parsedDate, os.date("*t") ) if ( age and age < 125) then result = result .. ' <span class="nowrap">(' .. age .. ' ' .. mw.language.new( 'ru' ):plural( age, 'год', 'года', 'лет') .. ')</span>' end if ( appendToCategory ) then if (not age and parsedDate and parsedDate.year ) then age = os.date('*t').year - parsedDate.year -- при неточной дате end if ( age ) then if ( age > 115 ) then result = result .. dateCat.categoryBigCurrentAge elseif ( age >= 0 ) then result = result .. dateCat.categoryBiographiesOfLivingPersons else result = result .. dateCat.categoryNegativeAge end end end end return result end function infocards.dateOfDeath( frame ) local new_args = infocards._getParameters( frame.args, {'dateOfBirth', 'dateOfDeath', 'nocat'} ) local dateOfBirth = new_args['dateOfBirth'] or '' local dateOfDeath = new_args['dateOfDeath'] or '' local nocat = new_args['nocat'] or mw.title.getCurrentTitle().nsText return infocards.dateOfDeathImpl( dateOfBirth, dateOfDeath, nocat ) end function infocards.dateOfDeathImpl( dateOfBirth, dateOfDeath, nocat ) if ( infocards.isBlank( dateOfDeath ) ) then return '' end local appendToCategory = infocards.isBlank( nocat ) if ( mw.ustring.match( dateOfDeath, '^%s*неизвестн.%s*$' ) ~= nil or mw.ustring.match( dateOfDeath, '^%s*%?%s*$' ) ~= nil ) then if ( appendToCategory ) then return "''неизвестно''" .. dateCat.categoryUnknownDeathDate else return "''неизвестно''" end end local parsedDateOfBirth = infocards.convertToDate ( dateOfBirth ) local parsedDateOfDeath = infocards.convertToDate ( dateOfDeath ) if ( parsedDateOfDeath == nil ) then --[[ Temporary hack in order to enable export dates to wikidata ]] local dDateStart = '<span class="no-wikidata" data-wikidata-property-id="P570">' local dDateEnd = '</span>' if ( appendToCategory ) then return dDateStart .. dateOfDeath .. dDateEnd .. dateCat.categoryManualWikification else return dDateStart .. dateOfDeath .. dDateEnd end end local result = infocards.formatDateImpl ( parsedDateOfDeath, 'dday', appendToCategory and 'Умершие' or nil ) if ( calculateAge ) then local age = infocards.age ( parsedDateOfBirth, parsedDateOfDeath ) if ( age and age > 0 ) then result = result .. ' <span class="nowrap">(' .. age .. ' ' .. mw.language.new( 'ru' ):plural( age, 'год', 'года', 'лет') .. ')</span>' end -- returns category to recently deceased persons local unixAvailable, unixDateOfDeath = pcall(function() local r = os.time(parsedDateOfDeath) if ( r ~= os.time() ) then return r end error() end) if (appendToCategory) then if ( unixAvailable and os.time() - unixDateOfDeath < 31536000 ) then result = result .. dateCat.categoryRecentlyDeceased elseif (age and age < 0) then result = result .. dateCat.categoryNegativeAge end end end return result end function infocards.age( parsedBirthDate, parsedFinishDate ) if ( parsedBirthDate == nil or parsedFinishDate == nil ) then return nil end local bd = parsedBirthDate["day"] local bm = parsedBirthDate["month"] local by = parsedBirthDate["year"] local dd = parsedFinishDate["day"] local dm = parsedFinishDate["month"] local dy = parsedFinishDate["year"] if ( bd and bm and by and dd and dm and dy ) then if ( dm > bm or ( dm == bm and dd >= bd ) ) then return dy - by else return dy - by - 1 end else return nil end end function infocards.formatDateImpl( parsedDate, infocardClass, categoryNamePrefix ) local datePart = '<span class="nowrap">' --Temporary hack in order to enable export dates to wikidata if infocardClass == "bday" then datePart = '<span class="no-wikidata" data-wikidata-property-id="P569">' elseif infocardClass == "dday" then datePart = '<span class="no-wikidata" data-wikidata-property-id="P570">' end local t1 = { day = parsedDate.osday, month = parsedDate.osmonth, year = parsedDate.osyear } local t2 = { day = parsedDate.day, month = parsedDate.month, year = parsedDate.year } datePart = datePart .. moduleDates.formatWikiImpl( t1, t2, infocardClass, categoryNamePrefix ) datePart = datePart .. '</span>' return datePart end function infocards.convertToDate( possibleDateString ) possibleDateString = mw.ustring.gsub( possibleDateString, '−', '-') local simpleDate = mw.ustring.match(possibleDateString, '^%s*([%-%d%.]+)%s*$', 0) if ( simpleDate ) then return infocards.convertToDateNewStylePart( simpleDate ) end local complexDate1, complexDate2 = mw.ustring.match(possibleDateString, '^%s*([%-%d%.]+)%s*%(([%-%d%.]+)%)%s*$', 0) if ( complexDate1 and complexDate2) then local table1 = infocards.convertToDateNewStylePart( complexDate1 ) local table2 = infocards.convertToDateOldStylePart( complexDate2 ) if ( table1 and table2 ) then return { year = table1["year"], month = table1["month"], day = table1["day"], osyear = table2["year"], osmonth = table2["month"], osday = table2["day"] } else return nil end end return nil end function infocards.convertToDateNewStylePart( possibleDateString ) local ny = mw.ustring.match(possibleDateString, '^(%-?%d+)$', 0) if (ny ~= nil) then return {year = tonumber(ny)} end return infocards.convertToDateCommonPart( possibleDateString ) end function infocards.convertToDateOldStylePart( possibleDateString ) local nd = mw.ustring.match(possibleDateString, '^(%-?%d+)$', 0) if (nd ~= nil) then return {day = tonumber(nd)} end return infocards.convertToDateCommonPart( possibleDateString ) end function infocards.convertToDateCommonPart( possibleDateString ) local sDay, sMonth, sYear local day, month, year sDay, sMonth, sYear = mw.ustring.match( possibleDateString, '^(%d?%d)%.(%d?%d)%.(%-?%d+)$', 0 ) if sDay ~= nil and sMonth ~= nil and sYear ~= nil then day = tonumber( sDay ) month = tonumber( sMonth ) year = tonumber( sYear ) if day >= 1 and day <= 32 and month >= 1 and month <= 12 then return { day = day, month = month, year = year } end end sDay, sMonth = mw.ustring.match( possibleDateString, '^(%d?%d)%.(%d?%d+)$', 0 ) if sDay ~= nil and sMonth ~= nil then day = tonumber( sDay ) month = tonumber( sMonth ) if day >= 1 and day <= 32 and month >= 1 and month <= 12 then return { day = day, month = month } end end sMonth, sYear = mw.ustring.match( possibleDateString, '^(%d?%d)%.(%-?%d+)$', 0 ) if sMonth ~= nil and sYear ~= nil then month = tonumber( sMonth ) year = tonumber( sYear ) if month >= 1 and month <= 12 then return { month = month, year = year } end end return nil end return infocards 6c1e746d6605d4d101f6aa9fd3e4824b60c64ef7 Модуль:Infocards/dateCat 828 278 718 717 2024-08-26T16:45:56Z DuOfOrl 5 1 версия импортирована Scribunto text/plain local p = {} p.categoryUnknownBirthDate = '[[Категория:Персоналии, чья дата рождения не установлена]]' p.categoryUnknownDeathDate = '[[Категория:Персоналии, чья дата смерти не установлена]]' p.categoryBigCurrentAge = '[[Категория:Персоналии с большим текущим возрастом]]' --бывш. [[Категория:Википедия:Статьи о персоналиях с большим текущим возрастом]] p.categoryNegativeAge = '[[Категория:Персоналии с отрицательным возрастом]]' -- p.categoryBigDeathAge = '[[Категория:Википедия:Статьи о персоналиях с большим возрастом во время смерти]]' //deleted -d.bratchuk 05-07-2016 p.categoryBiographiesOfLivingPersons = '[[Категория:Википедия:Биографии современников]]' p.categoryRecentlyDeceased = '[[Категория:Персоналии, умершие менее года назад]]' p.categoryManualWikification = '[[Категория:Википедия:Статьи с ручной викификацией дат в карточке]]' p.categoryNoBirthDate = '[[Категория:Персоналии без указанной даты рождения]]' --бывш. [[Категория:Википедия:Персоны без указанной даты рождения]] return p 6b27e44bc0a4aaafa42074ca16db92b13e4999d4 Модуль:String2 828 279 720 719 2024-08-26T16:45:56Z DuOfOrl 5 1 версия импортирована Scribunto text/plain --[[ Кое-какие дополнительные функции для строк ]] local M = { bs=function(f)-- первый параметр до начала второго параметра (или до конца, если он не встретился) --необяз. 3-й параметр - с какого по номеру (с 1) символа начинать поиск. return mw.ustring.sub(f.args[1], 1, (mw.ustring.find(f.args[1],f.args[2],tonumber(f.args[3] or 1),true) or 0)-1) end; as=function(f)-- первый параметр после начала второго параметра return mw.ustring.sub(f.args[1], (mw.ustring.find(f.args[1],f.args[2],1,true) or 0)+1) end; Tr=function(s,f,t,cf,df,sf)-- транслитерация первого параметра путём замены символов из второго параметра символами из третьего. -- Отдельными параметрами можно передавать флаги c, d и s, как в Perl; диапазоны в замене не работают, только в левой части -- (т.е. дефис надо передавать первым или последним). Второй результат - число заменённых символов local r, l, l2 = {}, mw.ustring.len(f), mw.ustring.len(t); for i = 1, l do r[mw.ustring.sub(f,i,i)] = i<=l2 and mw.ustring.sub(t,i,i) or df and '' or mw.ustring.sub(t,l2,l2) end local n2=0; local res, n = mw.ustring.gsub( s, ('[%s%s]%s'):format( cf and '^' or '', f:gsub('%','%%'):gsub(']','%]'):gsub('^%^','%^'), sf and '+' or '' ), sf and function(cc) n2 = n2+mw.ustring.len(cc)-1; return mw.ustring.gsub(cc,'.',r) end or r ) return res, n+n2 end; -- tr = function(f) return (M.Tr(f.args[1],f.args[2],f.args[3],f.args['c'],f.args['d'],f.args['s'])) end;-- транслитерировать -- trс = function(f) return ({M.Tr(f.args[1],f.args[2],f.args[3],f.args['c'],f.args['d'],f.args['s'])})[2] end;-- посчитать символы Trg = function(s,t,f,fi)-- Производит замену строк произвольной длины (если с fi, регистр не учитывает). -- Приоритет - по порядку в таблицах. for n,p in ipairs(t) do t[n] = {fi and mw.ustring.upper(p) or p,mw.ustring.len(p)} end local r,i,l,N = {},1,mw.ustring.len(s),0 while i<=l do (function() for n,p in ipairs(t) do if ( fi and mw.ustring.upper(mw.ustring.sub(s,i,i+p[2]-1)) or mw.ustring.sub(s,i,i+p[2]-1) ) == p[1] then table.insert(r,f[n]); i = i+p[2]; N=N+1; return end end table.insert(r,mw.ustring.sub(s,i,i)); i=i+1; return end)() end return table.concat(r),N end; trg = function(frame)--Работает с номерными аргументами шаблона,если задан параметр u, иначе со своими. -- Заменяет в первом аргументе аргументы 2, 4, 6... на аргументы 3, 5, 7... local tf, t, f, i= frame.args['u'] and frame.getParent() or f, {}, {}, 1; while tf.args[2*i] do t[tf.args[2*i]]=tf.args[2*i+1] or '' end return ( M.Trg(tf.args[1],t,f,(frame.args['i'] or '')~='') ) end; join = function (f) --объединяет нумерованные аргументы вызвавшего шаблона -- от from или 1 до to или первого отсутствующего -- через первый параметр invoke. Последний элемент можно присоединять иначе, задав второй параметр. -- По умолчанию ',' & 'и' -- Если 3-й параметр invoke — "s", строки из пробелов игнорируются; если "_", игнорируются пустые строки local t, tf, i = {}, f:getParent(), tonumber(f.args.from) or 1 local k,j,m = tonumber(f.args.to),i,f.args[3] while k and i<=k or tf.args[i] do if ( ({ ['_']=function(s)return s~=''end; ['s']=function(s)return not tostring(s):match("^%s*$")end })[m] or function() return true end )(tf.args[i]) then t[j]=tf.args[i]; j=j+1 end; i=i+1 end return mw.text.listToText(t,f.args[1],f.args[2] or f.args[1]) end } function M.formatRound(frame) --форматирует число, чтобы оно имело order знаков после запятой return string.format("%0."..frame.args[2].."f",tonumber(frame.args[1])); end -- если строка s содержит число, увеличивает первое такое число на n, иначе возращает пустую строку. -- если число начинается на 0, то увеличенное число будет содержать по крайне мере столько цифр сколько исходное. function M.increase(s, n) local a,b,c = string.match(s, "([^0-9]*)([0-9]+)(.*)") if b==nil then return s end local num = tonumber(b) + n if b:sub(1,1)=='0' then b = string.format("%0"..b:len().."d", num) else b=num end return a .. b .. c end function M.ucfirst(frame ) local s = mw.text.trim( frame.args[1] or "" ) local s1 = "" -- if it's a list chop off and (store as s1) everything up to the first <li> local lipos = string.find(s, "<li>" ) if lipos then s1 = string.sub(s, 1, lipos + 3) s = string.sub(s, lipos + 4) end -- s1 is either "" or the first part of the list markup, so we can continue -- and prepend s1 to the returned string local letterpos if string.find(s, "^%[%[[^|]+|[^%]]+%]%]") then -- this is a piped wikilink, so we capitalise the text, not the pipe local _ _, letterpos = string.find(s, "|%A*%a") -- find the first letter after the pipe else letterpos = string.find(s, '%a') end if letterpos then local first = string.sub(s, 1, letterpos - 1) local letter = string.sub(s, letterpos, letterpos) local rest = string.sub(s, letterpos + 1) return s1 .. first .. string.upper(letter) .. rest else return s1 .. s end end return M 1d51eb45a573b689485dad672c0968c18ec3b342 Модуль:Wikidata/date 828 280 722 721 2024-08-26T16:45:56Z DuOfOrl 5 1 версия импортирована Scribunto text/plain --settings local nowLabel = 'наст.&nbsp;время' local moduleDates = require( "Module:Dates" ) local moduleWikidata = require( "Module:Wikidata" ) local dateCat = require("Module:Infocards/dateCat") -- FIXME: undeclared global variable, used 3 times local infoclass local function deepcopy(orig) local orig_type = type(orig) local copy if orig_type == 'table' then copy = {} for orig_key, orig_value in next, orig, nil do copy[deepcopy(orig_key)] = deepcopy(orig_value) end setmetatable(copy, deepcopy(getmetatable(orig))) else -- number, string, boolean, etc copy = orig end return copy end local function ageImpl ( bStructure, bPrecision, dStructure, dPrecision ) if ( not bStructure or not dStructure or bPrecision < 10 or dPrecision < 10 ) then return nil end local shift = 0 if ( bStructure.year < 0 and dStructure.year > 0 ) then shift = -1 end if ( bPrecision == 10 or dPrecision == 10 ) then if ( bStructure.month < dStructure.month ) then return dStructure.year - bStructure.year + shift end if ( bStructure.month == dStructure.month ) then return nil end if ( bStructure.month > dStructure.month ) then return dStructure.year - bStructure.year - 1 + shift end end if ( bStructure.month < dStructure.month ) then return dStructure.year - bStructure.year + shift end if ( bStructure.month == dStructure.month ) then if ( bStructure.day <= dStructure.day ) then return dStructure.year - bStructure.year + shift else return dStructure.year - bStructure.year - 1 + shift end end if ( bStructure.month > dStructure.month ) then return dStructure.year - bStructure.year - 1 + shift end return nil end -- accepts table of time+precision values local function ageCurrent ( bTable ) local possibleAge = "NYA" -- it means "Not Yet Assigned", not what you imagined! for bKey, bValue in pairs(bTable) do if ( bValue.unknown ) then return nil end local bStructure = bValue.structure local bPrecision = bValue.precision local dStructure = os.date( "*t" ) local calculatedAge = ageImpl ( bStructure, bPrecision, dStructure, 11 ) if ( possibleAge == "NYA" ) then possibleAge = calculatedAge else if ( possibleAge ~= calculatedAge ) then possibleAge = nil end end end return possibleAge end -- accepts tables of time+precision values local function age ( bTable, dTable ) local possibleAge = "NYA" -- it means "Not Yet Assigned", not what you imagined! for bKey, bValue in pairs( bTable ) do if ( bValue.unknown ) then return nil end local bStructure = bValue.structure local bPrecision = bValue.precision for dKey, dValue in pairs( dTable ) do if ( dValue.unknown ) then return nil end local dStructure = dValue.structure local dPrecision = dValue.precision if ( bValue.calendar == 'julian' and dValue.calendar == 'gregorian' ) then -- to calculate age, need to adjust bStructure to gregorian calendar local shift = math.floor(bStructure.year/100-2) - math.floor(bStructure.year/400) -- TODO: re-implement this properly bStructure.day = bStructure.day + shift end local calculatedAge = ageImpl ( bStructure, bPrecision, dStructure, dPrecision ) if ( possibleAge == "NYA" ) then possibleAge = calculatedAge else if ( possibleAge ~= calculatedAge ) then possibleAge = nil end end end end return possibleAge end local function parseISO8601Date(str) local pattern = "(%-?%d+)%-(%d+)%-(%d+)T" local Y, M, D = mw.ustring.match( str, pattern ) return tonumber(Y), tonumber(M), tonumber(D) end local function parseISO8601Time(str) local pattern = "T(%d+):(%d+):(%d+)%Z" local H, M, S = mw.ustring.match( str, pattern) return tonumber(H), tonumber(M), tonumber(S) end local function parseISO8601Offset(str) if str:sub(-1)=="Z" then return 0,0 end -- ends with Z, Zulu time -- matches ±hh:mm, ±hhmm or ±hh; else returns nils local pattern = "([-+])(%d%d):?(%d?%d?)$" local sign, oh, om = mw.ustring.match( str, pattern) sign, oh, om = sign or "+", oh or "00", om or "00" return tonumber(sign .. oh), tonumber(sign .. om) end local function parseISO8601(str) if 'table' == type(str) then if str.args and str.args[1] then str = '' .. str.args[1] else return 'unknown argument type: ' .. type( str ) .. ': ' .. table.tostring( str ) end end local Y,M,D = parseISO8601Date(str) local h,m,s = parseISO8601Time(str) local oh,om = parseISO8601Offset(str) if not Y or not M or not D or not h or not m or not s or not oh or not om then return nil end return tonumber(os.time({year=Y, month=M, day=D, hour=(h+oh), min=(m+om), sec=s})) end local function parseClaim ( claim ) if ( claim.mainsnak.snaktype == "value" ) then local timeISO8601 = string.gsub( string.gsub( tostring( claim.mainsnak.datavalue.value.time ), '-00%-', '-01-' ), '-00T', '-01T' ) local unixtime = parseISO8601( timeISO8601 ) local structure = os.date("*t", unixtime) local precision = tonumber( claim.mainsnak.datavalue.value.precision ) local calendarmodel = 'gregorian' if (mw.ustring.find(claim.mainsnak.datavalue.value.calendarmodel, 'Q1985786', 1, true)) then calendarmodel = 'julian' end local item = { structure=structure, precision=precision, calendar = calendarmodel } return item elseif ( claim.mainsnak.snaktype == "novalue" ) then -- novalue return { unknown="novalue" } else --unknown return { unknown="unknown" } end end -- returns table of time+precision values for specified property local function parseProperty ( context, options, propertyId ) if ( not context ) then error( 'context not specified'); end if ( not options ) then error( 'options not specified'); end if ( not options.entity ) then error( 'options.entity is missing'); end if ( not propertyId ) then error( 'propertyId not specified'); end local claims = context.selectClaims( options, propertyId ) if not claims then return nil end local result = {} for key, claim in pairs( claims ) do table.insert ( result, parseClaim( claim ) ) end return result end -- проверка на совпадающие даты с разной моделью календаря local function checkDupDates( t ) if #t > 1 then local removed = false local j = 1 -- проверка на совпадающие даты с разной моделью календаря while (j <= #t) do local i = 1 while (i <= #t) do if i ~= j then if (os.time(t[j].structure) == os.time(t[i].structure)) then if ((t[j].calendarmodel == 'gregorian') and (t[i].calendarmodel == 'julian')) then removed = true break else table.remove(t, i) end else i = i + 1 end else i = i + 1 end end if removed then removed = false table.remove(t, j) else j = j+1 end end end end -- returns first qualifier of specified propertyId local function getQualifierWithDataValue( statement, qualifierPropertyId ) if ( statement.qualifiers and statement.qualifiers[qualifierPropertyId] ) then local qualifiers = statement.qualifiers[qualifierPropertyId] for _, qualifier in ipairs( qualifiers ) do if (qualifier.datavalue) then return qualifier end end end return nil end local p = {} local function formatDecade( time, categoryNamePrefix ) local bce = '' local year if time.year < 0 then bce = ' до н. э.' year = math.floor( math.abs( time.year ) / 10 ) * 10 else year = math.floor( time.year / 10 ) * 10 end local unit = '-е' if isGenitive then unit = '-х' end local value = '' .. year .. unit .. bce if categoryNamePrefix then return value .. '[[Category:' .. categoryNamePrefix .. ' в ' .. year .. '-е годы' .. bce .. ']]' end return value end local function formatCentury( time, categoryNamePrefix, isGenitive ) local moduleRoman = require( 'Module:RomanNumber' ) local bce = '' local century if time.year < 0 then bce = ' до н. э.' century = math.floor( ( math.abs( time.year ) - 1 ) / 100 ) + 1 else century = math.floor( ( time.year - 1 ) / 100 ) + 1 end local unit = 'век' if isGenitive then unit = 'века' end local infix = ' в ' if century == 2 then infix = ' во ' end if moduleRoman then century = moduleRoman.toRomanNumber( century ) end local value = '[[' .. century .. ' век' .. bce .. '|' .. century .. ' ' .. unit .. bce .. ']]' if categoryNamePrefix then return value .. '[[Category:' .. categoryNamePrefix .. infix .. century .. ' веке' .. bce .. ']]' end return value end local function formatMillenium( time, categoryNamePrefix, isGenitive ) local bce = '' local millenium if time.year < 0 then bce = ' до н. э.' millenium = math.floor( ( math.abs( time.year ) - 1 ) / 1000 ) + 1 else millenium = math.floor( ( time.year - 1 ) / 1000 ) + 1 end local unit = '-е тысячелетие' if isGenitive then unit = '-го тысячелетия' end local value = '[[' .. millenium .. '-е тысячелетие' .. bce .. '|' .. millenium .. unit .. bce .. ']]' if categoryNamePrefix then local infix = ' в ' if millenium == 2 then infix = ' во ' end return value .. '[[Category:' .. categoryNamePrefix .. infix .. millenium .. '-м тысячелетии' .. bce .. ']]' else return value end end local function formatDateImpl( value, options, microformatClass, categoryPrefix, leftBracket, rightBracket, nolinks, isGenitive ) if ( not value ) then error( 'value not specified'); end if ( not options ) then error( 'options not specified'); end -- The calendar model used for saving the data is always the proleptic Gregorian calendar according to ISO 8601. local timeISO8601 = string.gsub( string.gsub( tostring( value.time ), '-00%-', '-01-' ), '-00T', '-01T' ) local unixtime = parseISO8601( timeISO8601 ) if not unixtime then return '' end local structure = os.date("*t", unixtime) local precision = tonumber( value.precision ) if precision <= 6 then return formatMillenium( structure, categoryPrefix, isGenitive ) end if precision == 7 then return formatCentury( structure, categoryPrefix, isGenitive ) end if precision == 8 then return formatDecade( structure, categoryPrefix, isGenitive ) end if precision == 9 then local tCopy = deepcopy( structure ) tCopy.day = nil tCopy.month = nil return moduleDates.formatWikiImpl( tCopy, tCopy, infoclass, categoryPrefix, leftBracket, rightBracket, nolinks ) end -- year and month only if precision == 10 then local tCopy = deepcopy( structure ) tCopy.day = nil return moduleDates.formatWikiImpl( tCopy, tCopy, infoclass, categoryPrefix, leftBracket, rightBracket, nolinks ) end local calendarmodel = 'gregorian' if (mw.ustring.find(value.calendarmodel, 'Q1985786', 1, true)) then calendarmodel = 'julian' end if (calendarmodel == 'gregorian') then return moduleDates.formatWikiImpl( structure, structure, microformatClass, categoryPrefix, leftBracket, rightBracket, nolinks ) else return p.formatAsJulian( timeISO8601, infoclass, categoryPrefix, leftBracket, rightBracket, nolinks ) end end local function formatApproximateDateClaim( context, options, statement, unknownDateCategory ) if ( not context ) then error( 'context not specified'); end if ( not options ) then error( 'options not specified'); end if ( not options.entity ) then error( 'options.entity is missing'); end if ( not statement ) then error( 'statement not specified'); end if options.nocat then unknownDateCategory = "" end local qNotSoonerThan = getQualifierWithDataValue( statement, 'P1319' ) local qNotLaterThan = getQualifierWithDataValue( statement, 'P1326' ) if ( qNotSoonerThan or qNotLaterThan ) then local results = {} if ( qNotSoonerThan ) then local formattedDate = formatDateImpl( qNotSoonerThan.datavalue.value, {}, nil, nil, options.leftBracket, options.rightBracket, options.nolinks, true ) local value = 'не&nbsp;ранее&nbsp;' .. context.wrapSnak( formattedDate, qNotSoonerThan.hash ) table.insert( results, context.wrapQualifier( value, 'P1319' ) ) end if ( qNotLaterThan ) then local formattedDate = formatDateImpl( qNotLaterThan.datavalue.value, {}, nil, nil, options.leftBracket, options.rightBracket, options.nolinks, true ) local value = 'не&nbsp;позднее&nbsp;' .. context.wrapSnak( formattedDate, qNotLaterThan.hash ) table.insert( results, context.wrapQualifier( value, 'P1326' ) ) end return mw.text.listToText( results, ' и ' , ' и ' ) .. unknownDateCategory .. context.formatRefs( options, statement ) end return nil end function p.formatDateOfBirthClaim( context, options, statement ) local value = formatApproximateDateClaim( context, options, statement, dateCat.categoryUnknownBirthDate ) if value then return value end options['conjunction'] = '&#32;или&#32;' options['value-module'] = 'Wikidata/date' options['value-function'] = 'formatBirthDate' options.i18n.somevalue = '\'\'неизвестно\'\'' .. dateCat.categoryUnknownBirthDate local circumstances = context.getSourcingCircumstances( statement ) for _, itemId in ipairs( circumstances ) do if itemId == 'Q5727902' then options.isGenitive = true break end end local result = context.formatStatementDefault( context, options, statement ) local bTable = { parseClaim( statement ) } local dTable = parseProperty ( context, options, 'P570' ) if ( bTable and not dTable ) then local age = ageCurrent( bTable ) if ( age ) then if ( options.suppressAge == nil or options.suppressAge == '' ) then result = result .. ' <span style="white-space:nowrap;">(' .. age .. ' ' .. mw.language.new( 'ru' ):plural( age, 'год', 'года', 'лет') .. ')</span>' end if ( not options.nocat ) then if ( age > 115 ) then result = result .. dateCat.categoryBigCurrentAge elseif (age >= 0) then result = result .. dateCat.categoryBiographiesOfLivingPersons else result = result .. dateCat.categoryNegativeAge end end end end return result end function p.formatDateOfDeathClaim( context, options, statement ) local value = formatApproximateDateClaim( context, options, statement, dateCat.categoryUnknownDeathDate ) if value then return value end options['conjunction'] = '&#32;или&#32;' options['value-module'] = 'Wikidata/date' options['value-function'] = 'formatDeathDate' options.i18n.somevalue = '\'\'неизвестно\'\'' .. dateCat.categoryUnknownDeathDate local circumstances = context.getSourcingCircumstances( statement ) for _, itemId in ipairs( circumstances ) do if itemId == 'Q5727902' then options.isGenitive = true break end end local result = context.formatStatementDefault( context, options, statement ) local bTable = parseProperty ( context, options, 'P569' ) local dTable = { parseClaim( statement ) } if ( bTable and dTable ) then local age = age( bTable, dTable ) if ( age ) then if ( options.suppressAge == nil or options.suppressAge == '' ) then result = result .. ' <span style="white-space:nowrap;">(' .. age .. ' ' .. mw.language.new( 'ru' ):plural( age, 'год', 'года', 'лет') .. ')</span>' end if ( not options.nocat and age < 0) then result = result .. dateCat.categoryNegativeAge end end -- returns category to recently deceased persons local unixAvailable, unixDateOfDeath = pcall(function() local r = os.time(dTable[1].structure) if ( r ~= os.time() ) then return r end error() end) if ( unixAvailable and os.time() - unixDateOfDeath < 31536000 and not options.nocat ) then result = result .. dateCat.categoryRecentlyDeceased end end return result end -- Reentry point for Wikidata Snak formatting function p.formatBirthDate( context, options, value ) if ( not context ) then error( 'context not specified'); end if ( not options ) then error( 'options not specified'); end if ( not value ) then error( 'value not specified'); end local microformatClass = nil if options.microformat ~= '-' then microformatClass = options.microformat or 'bday' end if ( options.nocat ) then return formatDateImpl( value, options, microformatClass, nil, options.leftBracket, options.rightBracket, options.nolinks, options.isGenitive ) else return formatDateImpl( value, options, microformatClass, 'Родившиеся', options.leftBracket, options.rightBracket, options.nolinks, options.isGenitive ) end end -- Reentry point for Wikidata Snak formatting function p.formatDeathDate( context, options, value ) if ( not context ) then error( 'context not specified'); end if ( not options ) then error( 'options not specified'); end if ( not value ) then error( 'value not specified'); end local microformatClass = nil if options.microformat ~= '-' then microformatClass = options.microformat or 'dday' end if ( options.nocat and options.nocat ~= '' ) then return formatDateImpl( value, options, microformatClass, nil, options.leftBracket, options.rightBracket, options.nolinks, options.isGenitive ) else return formatDateImpl( value, options, microformatClass, 'Умершие', options.leftBracket, options.rightBracket, options.nolinks, options.isGenitive ) end end -- Reentry point for Wikidata Snak formatting -- default one function p.formatDate( context, options, value ) if ( not context ) then error( 'context not specified'); end if ( not options ) then error( 'options not specified'); end if ( not value ) then error( 'value not specified'); end local microformatClass = options.microformat or nil if ( options.nocat and options.nocat ~= '' ) then return formatDateImpl( value, options, microformatClass, nil, options.leftBracket, options.rightBracket, options.nolinks, options.isGenitive ) else local categoryPrefix = options.categoryPrefix or nil return formatDateImpl( value, options, microformatClass, categoryPrefix, options.leftBracket, options.rightBracket, options.nolinks, options.isGenitive ) end end function p.formatDateIntervalProperty( context, options ) if ( not context ) then error( 'context not specified' ); end if ( not options ) then error( 'options not specified' ); end if ( not options.entity ) then error( 'options.entity missing' ); end -- Получение нужных утверждений local WDS = require( 'Module:WikidataSelectors' ) local fromProperty = options.property if options.from and options.from ~= '' then fromProperty = options.from end local fromClaims = WDS.load( options.entityId, fromProperty ) local toClaims = WDS.load( options.entityId, options.to ) if fromClaims == nil and toClaims == nil then return '' end local formattedFromClaims = {} if fromClaims then for i, claim in ipairs( fromClaims ) do local formattedStatement = context.formatStatement( options, claim ) if formattedStatement then formattedStatement = '<span class="wikidata-claim" data-wikidata-property-id="' .. string.upper( options.property ) .. '" data-wikidata-claim-id="' .. claim.id .. '">' .. formattedStatement .. '</span>' table.insert( formattedFromClaims, formattedStatement ) end end end local formattedToClaims = {} local toOptions = deepcopy( options ) toOptions.property = options.to toOptions.novalue = nowLabel if toClaims then for i, claim in ipairs( toClaims ) do local formattedStatement = context.formatStatement( toOptions, claim ) if formattedStatement then formattedStatement = '<span class="wikidata-claim" data-wikidata-property-id="' .. string.upper( toOptions.property ) .. '" data-wikidata-claim-id="' .. claim.id .. '">' .. formattedStatement .. '</span>' table.insert( formattedToClaims, formattedStatement ) end end end local out = '' local fromOut = mw.text.listToText( formattedFromClaims, options.separator, options.conjunction ) local toOut = mw.text.listToText( formattedToClaims, options.separator, options.conjunction ) if fromOut ~= '' or toOut ~= '' then if fromOut ~= '' then out = fromOut else out = '?' end if toOut ~= '' then out = out .. ' — ' .. toOut else local withinClaims = nil if options.within then WDS.load( options.entityId, options.within ) end if withinClaims == nil then out = 'с ' .. out else out = out .. ' — ' .. nowLabel end end end if out ~= '' then if options.before then out = options.before .. out end if options.after then out = out .. options.after end end return out end local lowestBoundary = '1582-10-05T00:00:00Z' local lastBoundary = '1918-01-31T00:00:00Z' local boundaries = { -- from (G) till next will be diff(G = J + diff), at current { lowestBoundary, 10 }, { '1700-02-29T00:00:00Z', 11 }, { '1800-02-29T00:00:00Z', 12 }, { '1900-02-29T00:00:00Z', 13 }, { lastBoundary, '' }, } -- Передаваемое время обязано быть по Юлианскому календарю (старому стилю) function p.formatAsJulian( julTimeISO8601, infocardClass, categoryNamePrefix, leftBracket, rightBracket, nolinks ) if 'table' == type( julTimeISO8601 ) then if julTimeISO8601.args and julTimeISO8601.args[1] then julTimeISO8601 = julTimeISO8601.args[1] else return 'unknown argument type: ' .. type( julTime ) .. ': ' .. table.tostring( julTime ) end end julTimeISO8601 = mw.text.trim( julTimeISO8601 ) julTimeISO8601 = string.gsub( julTimeISO8601, '^+', '' ) local julTime = parseISO8601( julTimeISO8601 ) local t = os.date( "*t", julTime ) if ( julTime < parseISO8601( lowestBoundary ) ) then -- only julian if string.find( julTimeISO8601, '-02-29T', 1, true ) then t = { year = t.year, month = 2, day = 29 } end return moduleDates.formatWikiImpl( t, t, infocardClass, categoryNamePrefix, leftBracket, rightBracket, nolinks ) end if ( julTimeISO8601 >= lastBoundary ) then return "''некорректная дата (юлианский календарь не используется после 1918-01-26)''" end -- julian and grigorian for i = 1, #boundaries, 1 do local b1 = boundaries[i][1] local b2 = boundaries[i + 1][1] if ( b1 <= julTimeISO8601 and julTimeISO8601 < b2 ) then local diff = boundaries[i][2] if string.sub( julTimeISO8601, 1, 10 ) == string.sub( boundaries[i][1], 1, 10 ) then t = { year = t.year, month = 2, day = 29 } diff = diff - 1 end local gregTime = os.date( "*t", julTime + diff * 24 * 60 * 60 ) return moduleDates.formatWikiImpl( t, gregTime, infocardClass, categoryNamePrefix, leftBracket, rightBracket, nolinks ) end end return "''ошибка в модуле Модуль:Wikidata/date''" end return p 12c2c34efd103d2938bd65421aa550e8c6f26da0 Модуль:Dates 828 281 724 723 2024-08-26T16:45:57Z DuOfOrl 5 1 версия импортирована Scribunto text/plain --[[ В это модуле собраны функции, связанные с работой с датами. ]] local monthg = {'января', 'февраля', 'марта', 'апреля', 'мая', 'июня', 'июля', 'августа', "сентября", "октября", "ноября", "декабря"} local monthd = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} local function DecodeDate(d)-- Ч, М, Г, СЧ, СМ, СГ, хвост --дата: "%-?%d+"=год, "%d+%.%d+"=число месяца, "%d+%.%d+%.%-?%d+"=ЧМГ, -- потом в скобках м.б. переопределено для старого стиля начиная с числа local nd=d:match("^[%d.-]*"); local od=d:match("^[%d.-]*%s*%(%s*([%d.-]*)%s*%)"); local tail = d:match("^[%d.-]+%s*%(%s*[%d.-]+%s*%)%s*(%S.*)") or d:match("^[%d.-]+%s*([^%s%d].*)"); if nd:match('^%-?%d+$' ) then return nil, nil, tonumber(nd), nil, nil, od and tonumber(od:match("%-?%d+$")),tail else local j,m,y=nd:match("^(%d+)%.(%d+)%.?(%-?%d*)"); if j then if od then local oj, om, oy = od:match("^(%d+)%.?(%d*)%.?(%-?%d*)"); return j and tonumber(j), m and tonumber(m), y>'' and tonumber(y) or nil, oj and tonumber(oj), om>'' and tonumber(om) or nil, oy>'' and tonumber(oy) or nil, tail end return j and tonumber(j), m and tonumber(m), y>'' and tonumber(y) or nil, nil, nil, nil, tail else return nil end end end local function Diffy(d1,m1,y1,d0,m0,y0)--аналог Персона/Дата/Прошло лет return y1-y0 - ( y1*y0<=0 and 1 or 0 ) - ( (m1<m0 or m1==m0 and d1<d0) and 1 or 0 ) end local function Year0(y,t)-- аналог Год0 if y>0 then return table.concat{ '[[', tostring(y), ' год|', t and tostring(y)..'&nbsp;'..t or tostring(y), ']]' } else return table.concat{ '[[', tostring(-y), ' год до н. э.|', t and tostring(-y)..'&nbsp;'..t or tostring(-y), '&nbsp;до&nbsp;н.&nbsp;э.]]' } end end local function FormDate(j,m,y,oj,om,oy,mo)-- ~ Персона/Дата/Logic 4 if j then if not m then return "''формат неверен''" end if y then return string.format( '<span class="nowrap">%s<span style="display:none">(<span class="%s">%04i-%02i-%02i</span>)</span></span>', table.concat( oj and ( om and ( oy and {-- ДД ММММ ГГГГ ([[ДД ММММ]] [[ГГГГ]]) oj,'&nbsp;',monthg[om],'&nbsp;',oy, '</span> <span class="nowrap">([[', j, ' ', monthg[m],']] ',Year0(y),')' } or {-- ДД ММММ ([[ДД ММММ]]) [[ГГГГ]] oj,'&nbsp;',monthg[om],' ([[',j,'&nbsp;',monthg[m],']]) ',Year0(y) } ) or {-- ДД [[ДД ММММ|(ДД) ММММ]] [[ГГГГ]] oj,'&nbsp;[[',j,' ',monthg[m],'|','(',j,')&nbsp;',monthg[m],']] ',Year0(y) } ) or {'[[',j,'&nbsp;',monthg[m],']]&nbsp;',Year0(y)} ),--/table.concat ({['Рождения']='bday',['Смерти']='dday'})[mo] or '', y,m,j )--/string.format else return '<span class="nowrap">' .. table.concat( oj and ( om and {-- ДД ММММ ([[ДД ММММ]]) oj,'&nbsp;',monthg[om],' ([[',j,'&nbsp;',monthg[m],']])</span>' } or {-- ДД [[ДД ММММ|(ДД) ММММ]] oj,'&nbsp;[[',j,' ',monthg[m],'|','(',j,')&nbsp;',monthg[m],']]</span>' } ) or {'[[',j,'&nbsp;',monthg[m],']]</span>'} ) end else return y and string.format( '<span class="nowrap">%s<span style="display:none;">(<span class="bday">%04i</span>)</span></span>', Year0(y,'год'),y) or "''формат неверен''" end end local function GetDate(D)--dd.mm.-?yyyy или -?yyyy-mm-dd в три переменных d,m,y local d,m,y = d:match('^%s*(%d%d?)[/.]([01]?%d)[/.](%-?%d+)') if not d then y,m,d = D:match('^%s*(%-?%d+)[-\\]0*(1?%d)[-\\]0*(%d+)') end return tonumber(d),tonumber(m),tonumber(y) end local function Cmp(a,b)--Сравнивает две даты, результат соответственно -1, 0 или 1 local d1,m1,y1 = GetDate(a) local d2,m2,y2 = GetDate(b) return d1 and d2 and (--nil, если формат не опознан y1==y2 and ( m1==m2 and ( d1==d2 and 0 or d1<d2 and -1 or 1 ) or m1<m2 and -1 or 1 ) or y1<y2 and -1 or 1 ) end local function Yyyymmdd(r)--Переводит русскую дату в YYYY,MM,DD local d, m, y, M = mw.ustring.match(r, "^%s*(%d%d?)%s+([а-яА-Я]+)%s+(%d+)") if not m then return nil end m = mw.ustring.lower(m) --тупо перебор for i = 1, 12 do if m == monthg[i] then M = i break end end if not M then return nil end return tonumber(y), M, tonumber(d) end local p = {} p = { ifdate=function(f)-- Для шаблона "Если дата", имитирует старое поведение -- Аргументы передаются шаблону return f:getParent().args[ mw.ustring.match(frame.args[1],"^[ %d.%-−%()]*$") and 2 or 3 ] end; DecodeDate = DecodeDate; Diffy = Diffy; Year0 = Year0; GetDate = GetDate; Cmp = Cmp; Yyyymmdd = Yyyymmdd; diffy = function(f)-- принимает параметры #invoke в виде двух строк-дат local d1,m1,y1=DecodeDate(f.args[1]); local d0,m0,y0=DecodeDate(f.args[2]) return Diffy(d1,m1,y1,d0,m0,y0) end; monthg=function(f) return monthg[ f.args[1] or f:getParent().args[1] ] end;--realmonth persdate=function(f)-- Для шаблона Персона/Дата;{{#invoke:dates|persdate|nocat={{NAMESPACE}}}} local frame=f:getParent(); local catpref,mo,d,d2={['Рождения']='Родившиеся',['Смерти']='Умершие'}, frame.args[1],frame.args[2],frame.args[3] local cat, j,m,y,oj,om,oy,tail, j2,m2,y2, age = '' if d then j,m,y,oj,om,oy,tail=DecodeDate(d:gsub('−','-')); if not (j or y) then return (frame.args.nocat and d or d..'[[Category:Википедия:Статьи с ручной викификацией дат в карточке]]') end end; if d2 then j2,m2,y2 = DecodeDate(d2:gsub('−','-')); end; return table.concat{ FormDate(j,m,y,oj,om,oy,mo), ( (frame.args['nopersoncat'] or '')~='' or (f.args['nocat'] or '')~='' ) and '' or table.concat{ '[[Category:Персоналии по алфавиту]]', j and string.format('[[Category:%s %i %s]]',catpref[mo],j,monthg[m]) or '', y and string.format('[[Category:%s в %s]]',catpref[mo],y,Year0(y,'году')) or '' },--/table.concat внутр. (function(F)--возраст if not F then return '' end; local n=F(); return n and string.format(" (%i %s)%s", n, mw.getLanguage('ru'):plural(n,'год','года','лет'), n>150 and '[[Category:Википедия:Статьи о персоналиях с большим текущим возрастом]]' or '' ) or '' end)( ({ ['Рождения']=function() local now=os.date('*t'); if (not d2 or d2=='') and j and m and y then return Diffy(now.day,now.month,now.year,j,m,y) end end, ['Смерти']=function() return j and m and y and j2 and m2 and y2 and Diffy(j,m,y,j2,m2,y2); end, })[mo] ),--конец вызова функции возраста tail or '', cat }--/table.concat внеш. end; formdate=function(f) -- Формирует дату по 3--6 параметрам #invoke или шаблона --не использовать с пустыми аргументами if (f.args[1] or '')~='' and (f.args[2] or '')~='' or (f.args[3] or '')~='' then return FormDate(f.args[1],f.args[2],f.args[3],f.args[4],f.args[5],f.args[6],f.args['m']) else local tf=f:getParent(); return FormDate(tf.args[1],tf.args[2],tf.args[3],tf.args[4],tf.args[5],tf.args[6],tf.args['m']) end end; cmp=function(f)--Сравнивает две даты, результат соответственно -1, 0 или 1 return Cmp(f.args[1],f.args[2]) end; G2J=function(f)--перевод григорианских дат в юлианские, возврат DD.MM.YYYY --Не знает про 15 октября 1582 года, не работает до нашей эры и после ???99 года --Если есть второй аргумент, преобразует только ДО этой даты включительно --Если есть третий аргумент, результат форматирует под Персона/Дата local d,m,y=GetDate(f.args[1]) if f.args[2] and Cmp(f.args[1],f.args[2])==1 then return string.format("%i.%i.%i",d,m,y) end local shift=math.floor(y/100)-math.floor(y/400)-2 if d-shift>0 then return f.args[3] and string.format("%i.%i.%i (%i)",d,m,y,d-shift) or string.format("%i.%i.%i",d-shift,m,y) else if m==1 then return f.args[3] and string.format("%i.1.%i (%i.12.%i)",d,y,31+d-shift,y-1) or string.format("%i.12.%i",31+d-shift,y-1) elseif m==3 then return f.args[3] and string.format("%i.3.%i (%i.2)", d,y, (y%4==0 and 29 or 28)+d-shift-(y%100==0 and y%400~=0 and 1 or 0) ) or string.format("%i.2.%i", (y%4==0 and 29 or 28)+d-shift-(y%100==0 and y%400~=0 and 1 or 0) ,y) else return f.args[3] and string.format( "%i.%i.%i (%i.%i)", d,m,y, monthd[m-1]+d-shift,m-1 ) or string.format("%i.%i.%i",monthd[m-1]+d-shift,m-1,y) end end end; -- Переводит русскую дату в YYYY-MM-DD. Возвращает входное значение, если дата уже в этом формате yyyymmdd = function(f) local date, hourmin = f.args[1] if mw.ustring.match(date, "^%s*%d+\-%d+\-%d+") then return date end hourmin = mw.ustring.match(date, "%s+%d+:%d+$") local y, m, d = Yyyymmdd(date) if not y then return '<span class="error">Ошибка: некорректный формат даты.</span>' end return string.format('%4i-%02i-%02i', y, m, d) .. (hourmin or '') end } function table.val_to_str ( v ) if "string" == type( v ) then v = string.gsub( v, "\n", "\\n" ) if string.match( string.gsub(v,"[^'\"]",""), '^"+$' ) then return "'" .. v .. "'" end return '"' .. string.gsub(v,'"', '\\"' ) .. '"' else return "table" == type( v ) and table.tostring( v ) or tostring( v ) end end function table.key_to_str ( k ) if "string" == type( k ) and string.match( k, "^[_%a][_%a%d]*$" ) then return k else return "[" .. table.val_to_str( k ) .. "]" end end function table.tostring( tbl ) local result, done = {}, {} for k, v in ipairs( tbl ) do table.insert( result, table.val_to_str( v ) ) done[ k ] = true end for k, v in pairs( tbl ) do if not done[ k ] then table.insert( result, table.key_to_str( k ) .. "=" .. table.val_to_str( v ) ) end end return "{" .. table.concat( result, "," ) .. "}" end local function parseISO8601Date(str) local pattern = "(%-?%d+)%-(%d+)%-(%d+)T" local Y, M, D = mw.ustring.match( str, pattern ) return tonumber(Y), tonumber(M), tonumber(D) end local function parseISO8601Time(str) local pattern = "T(%d+):(%d+):(%d+)%Z" local H, M, S = mw.ustring.match( str, pattern) return tonumber(H), tonumber(M), tonumber(S) end local function parseISO8601Offset(str) if str:sub(-1)=="Z" then return 0,0 end -- ends with Z, Zulu time -- matches ±hh:mm, ±hhmm or ±hh; else returns nils local pattern = "([-+])(%d%d):?(%d?%d?)$" local sign, oh, om = mw.ustring.match( str, pattern) sign, oh, om = sign or "+", oh or "00", om or "00" return tonumber(sign .. oh), tonumber(sign .. om) end function p.parseISO8601(str) if 'table'==type(str) then if str.args and str.args[1] then str = '' .. str.args[1] else return 'unknown argument type: ' .. type( str ) .. ': ' .. table.tostring( str ) end end local Y,M,D = parseISO8601Date(str) local h,m,s = parseISO8601Time(str) local oh,om = parseISO8601Offset(str) return tonumber(os.time({year=Y, month=M, day=D, hour=(h+oh), min=(m+om), sec=s})) end local g2uBoundary1 = p.parseISO8601('1582-10-15T00:00:00Z') local g2uBoundary2 = p.parseISO8601('1700-03-12T00:00:00Z') local g2uBoundary3 = p.parseISO8601('1800-03-13T00:00:00Z') local g2uBoundary4 = p.parseISO8601('1900-03-14T00:00:00Z') local g2uBoundary5 = p.parseISO8601('1918-01-26T00:00:00Z') -- декрет Ленина -- Передаваемое время обязано быть по Григорианскому календарю (новому стилю) function p.formatWiki( time, infocardClass, categoryNamePrefix ) if 'table'==type( time ) then if time.args and time.args[1] then time = tonumber( time.args[1] ) else return 'unknown argument type: ' .. type( time ) .. ': ' .. table.tostring( time ) end end local t = os.date("*t", time) if time < g2uBoundary1 then -- выводим просто юлианский календарь. Задавать тут григорианский некорректно return p.formatWikiImpl( t, t, infocardClass, categoryNamePrefix ) end -- Специальные даты if t.year == 1700 and t.month == 3 and t.day == 11 then return p.formatWikiImpl( {year=1700, month=2, day=29}, t, infocardClass, categoryNamePrefix) end if t.year == 1800 and t.month == 3 and t.day == 12 then return p.formatWikiImpl( {year=1800, month=2, day=29}, t, infocardClass, categoryNamePrefix ) end if t.year == 1900 and t.month == 3 and t.day == 13 then return p.formatWikiImpl( {year=1900, month=2, day=29}, t, infocardClass, categoryNamePrefix ) end if g2uBoundary1 <= time and time < g2uBoundary2 then return p.formatWikiImpl( os.date("*t", time - 10 * 24 * 60 * 60), t, infocardClass, categoryNamePrefix ) end if g2uBoundary2 <= time and time < g2uBoundary3 then return p.formatWikiImpl( os.date("*t", time - 11 * 24 * 60 * 60), t, infocardClass, categoryNamePrefix ) end if g2uBoundary3 <= time and time < g2uBoundary4 then return p.formatWikiImpl( os.date("*t", time - 12 * 24 * 60 * 60), t, infocardClass, categoryNamePrefix ) end if g2uBoundary4 <= time and time < g2uBoundary5 then return p.formatWikiImpl( os.date("*t", time - 13 * 24 * 60 * 60), t, infocardClass, categoryNamePrefix ) end --только Григорианский календарь return p.formatWikiImpl( t, t, infocardClass, categoryNamePrefix ) end local function ternary ( cond , T , F ) if cond then return T else return F end end local nominativeMonthes = {'январь', 'февраль', 'март', 'апрель', 'май', 'июнь', 'июль', 'август', 'сентябрь', 'октябрь', 'ноябрь', 'декабрь'} local genitivusMonthes = {'января', 'февраля', 'марта', 'апреля', 'мая', 'июня', 'июля', 'августа', 'сентября', 'октября', 'ноября', 'декабря'} local function nominativeYear( year, nolinks ) if ( year >= 0 ) then return nolinks and year or '[[' .. year .. ' год|' .. year .. ']]' else return nolinks and ( 0 - year ) .. ' до н. э.' or '[[' .. ( 0 - year ) .. ' год до н. э.|' .. ( 0 - year ) .. ' до н. э.]]' end end local function inYear( year ) if ( year >= 0 ) then return '' .. year .. ' году' else return '' .. ( 0 - year) .. ' году до н. э.' end end function p.formatWikiImpl( t1, t2, infocardClass, categoryNamePrefix, leftBracket, rightBracket, nolinks ) local nd = t2.day; local nm = t2.month; local ny = t2.year; local od = ternary ( t1.day ~= t2.day , t1.day, nil ); local om = ternary ( t1.month ~= t2.month , t1.month, nil ); local oy = ternary ( t1.year ~= t2.year , t1.year, nil ); if leftBracket == nil then leftBracket = '(' end if rightBracket == nil then rightBracket = ')' end local JulianComment = function(s) return tostring(mw.html.create("abbr") :attr("title","по юлианскому календарю") :wikitext(s) :done()) end local template = (nd ~= nil and "1" or "") .. (nm ~= nil and "2" or "") .. (ny ~= nil and "3" or "") .. (od ~= nil and "4" or "") .. (om ~= nil and "5" or "") .. (oy ~= nil and "6" or "") local datePart = '<span class="nowrap">' if (template == "12") then datePart = datePart .. string.format( nolinks and "%d %s" or "[[%d %s]]", nd, genitivusMonthes[nm] ) elseif (template == "23") then datePart = datePart .. string.format( "%s %s", nominativeMonthes[nm], nominativeYear( ny, nolinks ) ) elseif (template == "3") then datePart = datePart .. nominativeYear( ny, nolinks ) elseif (template == "123") then datePart = datePart .. string.format( nolinks and "%d %s %s" or "[[%d %s]] %s", nd, genitivusMonthes[nm], nominativeYear( ny, nolinks ) ) elseif (template == "124") then if nolinks then datePart = datePart .. JulianComment(string.format( "%d", od ) ).. string.format( " " .. leftBracket .. "%d" .. rightBracket .. " %s", nd, genitivusMonthes[nm] ) else datePart = datePart .. JulianComment(string.format( "%d", od ) ).. string.format( " [[%d %s|" .. leftBracket .. "%d" .. rightBracket .. " %s]]", nd, genitivusMonthes[nm], nd, genitivusMonthes[nm] ) end elseif (template == "1234") then if nolinks then datePart = datePart .. JulianComment(string.format( "%d", od ) ).. string.format( " |" .. leftBracket .. "%d" .. rightBracket .. " %s %s", nd, genitivusMonthes[nm], nominativeYear( ny, nolinks ) ) else datePart = datePart .. JulianComment(string.format( "%d", od ) ).. string.format( " [[%d %s|" .. leftBracket .. "%d" .. rightBracket .. " %s]] %s", nd, genitivusMonthes[nm], nd, genitivusMonthes[nm], nominativeYear( ny, nolinks ) ) end elseif (template == "1245") then datePart = datePart .. JulianComment(string.format( "%d %s", od, genitivusMonthes[om] ) ).. string.format(" " .. leftBracket .. (nolinks and "%d %s" or "[[%d %s]]") .. rightBracket .. "", nd, genitivusMonthes[nm] ) elseif (template == "12345") then datePart = datePart .. JulianComment(string.format( "%d %s", od, genitivusMonthes[om] ) ).. string.format(" " .. leftBracket .. (nolinks and "%d %s" or "[[%d %s]]") .. rightBracket .. " %s", nd, genitivusMonthes[nm], nominativeYear( ny, nolinks ) ) elseif (template == "123456") then datePart = datePart .. JulianComment(string.format( "%d %s %d", od, genitivusMonthes[om], oy )) .. '</span> <span class="nowrap">' .. string.format(" " .. leftBracket .. (nolinks and "%d %s %s" or "[[%d %s]] %s") .. rightBracket , nd, genitivusMonthes[nm], nominativeYear( ny, nolinks ) ) else datePart = datePart .. 'формат неверен' end datePart = datePart .. '</span>' local infocardTemplate = (nd ~= nil and "1" or "") .. (nm ~= nil and "2" or "") .. (ny ~= nil and "3" or "") if infocardClass then if (infocardTemplate == "123") then datePart = datePart .. string.format('<span style="display:none">(<span class="%s">%04d-%02d-%02d</span>)</span>', infocardClass , ny , nm , nd ) elseif (infocardTemplate == "23") then datePart = datePart .. string.format('<span style="display:none">(<span class="%s">%04d-%02d</span>)</span>', infocardClass , ny , nm ) elseif (infocardTemplate == "3") then datePart = datePart .. string.format('<span style="display:none;">(<span class="%s">%04d</span>)</span>', infocardClass , ny ) end end if categoryNamePrefix then if ( nd ~= nil and nm ~= nil) then datePart = datePart .. '[[Category:' .. categoryNamePrefix .. ' ' .. nd .. ' ' .. genitivusMonthes[nm] .. ']]' end if ( ny ~= nil) then datePart = datePart .. '[[Category:' .. categoryNamePrefix .. ' в ' .. inYear( ny ) .. ']]' end end return datePart end return p 902bb6a9ef5ce12ad4cfa19f3d2c964d7e092df7 Шаблон:Lang-en 10 282 726 725 2024-08-26T16:45:57Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <nowiki />[[английский язык|англ.]]&nbsp;{{lang-en2|{{{1}}}}}<noinclude> {{doc|Lang/doc}} </noinclude> 6fcc1d4dc63f133033671bf27e48a6e701e126cb Шаблон:Lang-en2 10 283 728 727 2024-08-26T16:45:57Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{langi|en|{{{1}}}}}<noinclude> {{doc|Lang/doc}} </noinclude> 0471cf4d45a13ece481915d5c3e55db65d6aca04 Модуль:Wikidata/Medals 828 284 730 729 2024-08-26T16:45:59Z DuOfOrl 5 1 версия импортирована Scribunto text/plain local WDS = require( 'Module:WikidataSelectors' ) local moduleDate = require( 'Module:Wikidata/date' ) local awardsOrder = mw.ext.data.get( "Wikidata/awards order.tab" ) local p = {} local config = { --Hide award with key QID if there is a reward with value QID absorption = { Q16675272 = 'Q654471', Q16481808 = 'Q8706404', Q1948730 = 'Q178473', Q1980962 = 'Q208167', Q2032399 = 'Q2046996', Q102183407 = 'Q103819965', Q1262166 = 'Q80589', Q749849 = 'Q1358055', Q4287121 = 'Q4137462', } } --Get string with dates from qualifiers table local function datesFromQualifier( context, options, qualifierId ) local dates = {} local qualifiers = options.qualifiers[ qualifierId ] if qualifiers then for _, qualifier in pairs( qualifiers ) do if qualifier.datavalue then local dateValue = moduleDate.formatDate( context, options, qualifier.datavalue.value ) if dateValue then table.insert( dates, dateValue ) end end end end return table.concat( dates, ', ' ) end --Property function for [[d:Property:P166]] function p.formatProperty( context, options ) if ( not context ) then error( 'context not specified' ); end; if ( not options ) then error( 'options not specified' ); end; if ( not options.entityId ) then error( 'options.entityId missing' ); end; local claims; if options.property then -- TODO: Почему тут может не быть property? claims = context.selectClaims( options, options.property ); end if claims == nil then return '' --TODO error? end -- Обход всех заявлений утверждения и с накоплением оформленых -- предпочтительных заявлений в таблице. local formattedData = {} for i, claim in ipairs( claims ) do if ( claim.mainsnak and claim.mainsnak and claim.mainsnak.datavalue and claim.mainsnak.datavalue.type == 'wikibase-entityid' ) then local valueId = claim.mainsnak.datavalue.value.id local formattedStatement = context.formatStatement( options, claim ) -- здесь может вернуться либо оформленный текст заявления, либо строка ошибки, либо nil if ( formattedStatement and formattedStatement ~= '' ) then formattedStatement = '<span class="wikidata-claim" data-wikidata-property-id="' .. string.upper( options.property ) .. '" data-wikidata-claim-id="' .. claim.id .. '">' .. formattedStatement .. '</span>' table.insert( formattedData, { id = valueId, html = formattedStatement, } ) end end end -- Удаление дублей (медаль + звание -> звание) for i, awardData in ipairs( formattedData ) do local isAbsorptionFound = false if config.absorption[ awardData.id ] then local absorptionAwardId = config.absorption[ awardData.id ] for _, absorptionAwardData in ipairs( formattedData ) do if absorptionAwardData.id == absorptionAwardId then isAbsorptionFound = true break end end end if isAbsorptionFound then table.remove( formattedData, i ) end end -- Сортировка медалей по старшинству local orderedData = {} local lastValue; if ( type (awardsOrder) == 'table' ) then -- Если не отсохла stuctured data for i, awardFields in ipairs( awardsOrder.data ) do local awardOrder = awardFields[ 1 ] if awardOrder == '-' then -- separator if lastValue ~= '-' then table.insert( orderedData, '<br>' ) lastHeight = nil end else for k, awardData in ipairs( formattedData ) do if awardOrder == awardData.id and not awardData.used then table.insert( orderedData, awardData.html ) formattedData[ k ].used = true end end end end end for i, awardData in ipairs( formattedData ) do if not awardData.used then table.insert( orderedData, awardData.html ) end end local lastHeight for i, awardHtml in ipairs( orderedData ) do local height = mw.ustring.match( awardHtml, 'x%d+px' ) if height and lastHeight and height ~= lastHeight then table.insert( orderedData, i, '<br>' ) end lastHeight = height end -- создание текстовой строки со списком оформленых заявлений из таблицы local out = mw.text.listToText( orderedData, options.separator, options.conjunction ) if out ~= '' then if options.before then out = options.before .. out end if options.after then out = out .. options.after end end return out end local function getImageFromProperty( entityId, propertyId ) local imageClaims = WDS.load( entityId, propertyId ) if imageClaims and #imageClaims > 0 then for _, claim in ipairs( imageClaims ) do if claim.type == 'statement' and claim.mainsnak.snaktype == 'value' then return claim.mainsnak.datavalue.value end end end return nil end -- Получение изображения (планки или иконки) и его размера function p.getImageFromEntity( entityId, actualDate ) if type( entityId ) ~= "string" then entityId = entityId.id end local image = nil local size = 'x17px' local border = false -- получение изображения планки из элемента image = getImageFromProperty( entityId, 'P2425' ) if image then border = true end -- получение иконки из элемента if not image then image = getImageFromProperty( entityId, 'P2910' ) if image then size = '40x40px' end end return image, size, border end --Value function for [[d:Property:P166]] function p.formatValue( context, options, statement ) local entityId = statement.id if not entityId then return statement end local label = mw.wikibase.getLabel( entityId ) local image, size, border = p.getImageFromEntity( entityId ) local recipientCategory = '' if not options.nocat and options.nocat ~= '' then recipientCategory = context.extractCategory( { category = 'P7084[P4224:Q24571879]' }, entityId ) if recipientCategory == '' then recipientCategory = context.extractCategory( { category = 'P2517' }, entityId ) end end local dates = '' if options.qualifiers then local startDates = {} dates = datesFromQualifier( context, options, 'P580' ) if dates ~= '' then local endDates = datesFromQualifier( context, options, 'P582' ) if endDates and endDates ~= '' then dates = dates .. ' — ' .. endDates end else dates = datesFromQualifier( context, options, 'P585' ) end if options.qualifiers.P27 then mw.log('>>>>>>>>>>>>>') for _, claim in ipairs( options.qualifiers.P27 ) do if claim and claim.datavalue and claim.datavalue.value and claim.datavalue.value.id then local categoryOptions = { category = 'P7084[P27:' .. claim.datavalue.value.id .. ']' } recipientCategory = recipientCategory .. context.extractCategory( categoryOptions, entityId ) end end end end -- получение ссылки по идентификатору и вывод планки if image then local link = mw.wikibase.getSitelink( entityId ) local out = '[[File:' .. image if border == true then out = out .. '|border' end out = out .. '|' .. size .. '|link=' -- получение ссылки из родительского элемента -- для степеней обычно только одна общая статья if not link then local partOfClaims = WDS.load( entityId, 'P361' ) -- часть от if not partOfClaims or #partOfClaims == 0 then partOfClaims = WDS.load( entityId, 'P279' ) -- подкласс от end if partOfClaims and #partOfClaims > 0 then for _, claim in ipairs( partOfClaims ) do if claim.type == 'statement' and claim.mainsnak.snaktype == 'value' then link = mw.wikibase.getSitelink( claim.mainsnak.datavalue.value.id ) if link then break end end end end end if link then out = out .. link else out = out .. 'd:' .. entityId end if label then out = out .. '|' .. label end out = out .. ']]' out = out .. recipientCategory return out end local out = context.formatValueDefault( context, options, statement ) if out and out ~= '' then if dates ~= '' then out = out .. ' (' .. dates .. ')' end return '<span style="display:inline-block; text-align:left>' .. out .. recipientCategory .. '</span>' end return '' end --Table for documentation function p.renderDoc() local out = {} for i, awardFields in ipairs( awardsOrder.data ) do local awardId = awardFields[ 1 ] local link = '[[d:' .. awardId .. '|' .. awardId .. ']]' if i == 351 then -- limits table.insert( out, '| … || … || … || … || …' ) elseif i > 351 and i < #awardsOrder.data then -- do nothing elseif awardId == '-' then -- separator table.insert( out, '|' .. i .. '|| colspan="3" | ----' ) else local image, size, border = p.getImageFromEntity( awardId ) if image then image = '[[File:' .. image if border == true then image = image .. '|border' end image = image .. '|' .. size .. ']]' else image = '' end local label = mw.wikibase.getLabel( awardId ) or '' local article = mw.wikibase.getSitelink( awardId ) if article then if label == '' then label = article end label = '[[' .. article .. '|' .. label .. ']]' end local countryStatements = mw.wikibase.getBestStatements( awardId, 'P17' ) local countries = {} if countryStatements then for _, statement in ipairs( countryStatements ) do if statement.mainsnak.datavalue and statement.mainsnak.datavalue.type == 'wikibase-entityid' then local countryId = statement.mainsnak.datavalue.value.id table.insert( countries, mw.wikibase.getLabel( countryId ) ) end end end table.insert( out, '|' .. i .. '||' .. link .. '||' .. image .. '||' .. label .. '||' .. table.concat( countries, ', ' ) ) end end return '{| class="wikitable"\n' .. '! # !! Элемент !! Планка !! Название !! Государство\n|-\n' .. table.concat( out, '\n|-\n' ) .. '\n|}' end return p 4de64e0e2181e8a4487f3e18da893fca9f92660d Модуль:Wikidata/url 828 285 732 731 2024-08-26T16:46:01Z DuOfOrl 5 1 версия импортирована Scribunto text/plain local p = {} local function formatLangRefs( options ) local langRefs = {} if options.qualifiers and options.qualifiers.P407 then for _, qualifier in ipairs( options.qualifiers.P407 ) do if ( qualifier and qualifier.datavalue and qualifier.datavalue.type == 'wikibase-entityid' ) then local qualifierId = qualifier.datavalue.value.id local wbStatus, langRefCodeClaims = pcall( mw.wikibase.getBestStatements, qualifierId, 'P218' ) if wbStatus and langRefCodeClaims then for _, claim in ipairs( langRefCodeClaims ) do if ( claim.mainsnak and claim.mainsnak.datavalue and claim.mainsnak.datavalue.type == 'string' ) then local langRefCode = claim.mainsnak.datavalue.value table.insert( langRefs, options.frame:expandTemplate{ title = 'ref-' .. langRefCode } ) end end end end end end return table.concat( langRefs, '&#8203;' ) end function p.formatUrlValue( context, options, value ) local moduleUrl = require( 'Module:URL' ) local langRefs = formatLangRefs( options ) if not options.length or options.length == '' then options.length = math.max( 18, 25 - #langRefs ) end return moduleUrl.formatUrlSingle( context, options, value ) .. langRefs end return p 4a9959f45666b35899729e561a73e0535c16e15e Модуль:Wikidata/P512 828 286 734 733 2024-08-26T16:46:01Z DuOfOrl 5 1 версия импортирована Scribunto text/plain local p = {} --[[ Функция формирует строку с викиразметкой для переданного свойства Принимает: объект контекста для вызова форматтеров и таблицу настройек Возвращает: вики-форматированную строку ]] function p.formatAcademicDegree( context, options ) if ( not context ) then error( 'context not specified' ); end; if ( not options ) then error( 'options not specified' ); end; if ( not options.entity ) then error( 'options.entity missing' ); end; local claims = context.selectClaims( options, options.property ); if (claims == nil) then return '' end local blackList = p.getPreviousDegrees( claims ) local formattedClaims = {} for i, claim in ipairs(claims) do if (claim.mainsnak.datavalue and not blackList[claim.mainsnak.datavalue.value['numeric-id']]) then local formattedStatement = context.formatStatement( options, claim ) if (formattedStatement) then formattedStatement = '<span class="wikidata-claim"' .. ' data-wikidata-property-id="' .. string.upper( options.property ) .. '" data-wikidata-claim-id="' .. claim.id .. '">' .. formattedStatement .. '</span>' if (claim.qualifiers) then formattedStatement = formattedStatement .. p.formatQualifier( context, options, claim.qualifiers.P585 ) end formattedStatement = formattedStatement .. p.formatCorrespondingCategory( claim ) table.insert( formattedClaims, formattedStatement ) end end end -- создание текстовой строки со списком оформленых заявлений из таблицы return mw.text.listToText( formattedClaims, options.separator, options.conjunction ); end --[[ Функция помещает в скобки текст первого квалификатора из переданной таблицы Принимает: объект контекста для вызова форматтеров, таблицу настроеки и таблицу квалификаторов Возвращает: отформатированная строка с квалификатором ]] function p.formatQualifier( context, options, qualifiers ) if (qualifiers~=nil and qualifiers[1] ~= nil) then return ' (' .. context.formatSnak( options, qualifiers[1] ) .. ')' end return '' end --[[ Функция формирует список соответствующих ученых степеней нижней ступени (P155) Например, для "доктор искусствоведения" это будет "кандидат искусствоведения" Принимает: объект таблицу сущностей - академических степеней персоны (P512) Возвращает: объект таблицу идентификаторов степеней нижней ступени ]] function p.getPreviousDegrees( claims ) -- Пока нет нормальной возможности загружать элементы c кэшем -- снаружи Module:Wikidata, мы эти соответствия захардкодим (без Q) local correspondingCandidates = { [16698078] = 19610224, -- архитектор [17281188] = 19610186, -- биолог [17281187] = 19610187, -- ветеринар [17281186] = 19610193, -- военный [16698080] = 19610195, -- географ [16698082] = 19610197, -- гео-мин [17281180] = 18523814, -- искусствовед [12101789] = 18523811, -- историк [16698084] = 19610200, -- культуролог [17281165] = 19610203, -- медик [17281161] = 19610206, -- педагог [12101787] = 4212319, -- политолог [17281156] = 19610208, -- психолог [17281153] = 19610210, -- сель-хоз [17281152] = 19610212, -- социолог [17281125] = 18071588, -- техник [17281115] = 19610228, -- фармацевт [17281097] = 18002832, -- физ-мат [17281087] = 19603970, -- филолог [17281084] = 19603972, -- философ [17281079] = 19610312, -- химик [17281072] = 17744738, -- экономист [18745564] = 19610320 -- юрист } local previousElements = {} for i, claim in ipairs(claims) do if(claim.mainsnak.datavalue) then local entityId = claim.mainsnak.datavalue.value['numeric-id'] if (entityId) then if correspondingCandidates[entityId] then previousElements[correspondingCandidates[entityId]] = true end end end end return previousElements end --[[ Функция формирует вики-разметку категории, соответствующей ученой степени Принимает: объект таблицу утверждения Возвращает: строку оформленного текста либо пустую строку ]] function p.formatCorrespondingCategory (claim) if ( not claim ) then return '' end; if ( not claim.mainsnak ) then return '' end; if claim.mainsnak.datavalue.value['numeric-id'] == 752297 then return '' end local label = mw.wikibase.label("Q" .. claim.mainsnak.datavalue.value['numeric-id']) if not label then label = '' end local result, changes = string.gsub(label, "доктор ", "Категория:Доктора ") if (changes == 1) then return '[[' .. result .. ']]' end result, changes = string.gsub(label, "кандидат ", "Категория:Кандидаты ") if (changes == 1) then return '[[' .. result .. ']]' end return '' end return p dea2568f9f334dcfc745eca69d76f89255ac1b2c Шаблон:Родственный проект 10 287 736 735 2024-08-26T16:46:02Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <templatestyles src="Шаблон:Родственный_проект/styles.css" /> {| role="presentation" class="metadata plainlinks ts-Родственный_проект noprint ruwikiWikimediaNavigation" |- ! style="width:10%;" | [[Файл:{{#switch: {{lc:{{{проект|}}}}} | commons|викисклад = Notification-icon-Commons-logo.svg | meta|metawiki|m|мета|метавики = Notification-icon-Meta-logo.svg | wikibooks|wbk|wb|b|викиучебник = Notification-icon-Wikibooks-logo.svg | wikidata|data|викиданные = Notification-icon-Wikidata-logo.svg | wikiquote|quote|wqt|q|викицитатник = Notification-icon-Wikiquote.svg | wikipedia|wp|w|википедия = Notification-icon-Wikipedia-logo.svg | wikisource|source|ws|s|викитека = Notification-icon-Wikisource-logo.svg | wiktionary|wkt|wdy|d|wikt|викисловарь = Notification-icon-Wiktionary-logo.svg | wikinews|news|wnw|n|викиновости = Notification-icon-Wikinews-logo.svg | wikispecies|species|викивиды = Notification-icon-Wikispecies-logo.svg | wikiversity|wvy|v|викиверситет = Notification-icon-Wikiversity-logo.svg | wikivoyage|voyage|voy|викигид = Notification-icon-Wikivoyage-logo.svg | mediawiki|mw|медиа|медиавики = MediaWiki-2020-small-icon.svg | outreachwiki|outreach = Wikimedia Outreach.svg | incubator|инкубатор = Notification-icon-Incubator-logo.svg | #default = Wikimedia-logo-update-2016.svg }}|24px|class=noviewer {{#switch: {{lc:{{{проект|}}}}} | wikipedia|wp|w|википедия = skin-invert-image }}|alt={{#switch: {{lc:{{{проект|}}}}} | commons|викисклад = Логотип Викисклада | meta|metawiki|m|мета|метавики = Логотип Метавики | wikibooks|wbk|wb|b|викиучебник = Логотип Викиучебника | wikidata|data|викиданные = Логотип Викиданных | wikiquote|quote|wqt|q|викицитатник = Логотип Викицитатника | wikipedia|wp|w|википедия = Логотип Википедии | wikisource|source|ws|s|викитека = Логотип Викитеки | wiktionary|wkt|wdy|d|wikt|викисловарь = Логотип Викисловаря | wikinews|news|wnw|n|викиновости = Логотип Викиновостей | wikispecies|species|викивиды = Логотип Викивидов | wikiversity|wvy|v|викиверситет = Логотип Викиверситета | wikivoyage|voyage|voy|викигид = Логотип Викигида | mediawiki|mw|медиа|медиавики = Логотип Медиавики | outreachwiki|outreach = Логотип «Викимедия Популяризация» | incubator|инкубатор = Логотип Инкубатора | #default = Логотип Викимедии }}|link=]] | {{{текст|}}} {{#if: {{{внизу|}}} | {{!-}} {{!}} colspan="2" class="noplainlist" style="text-weight:bold;" {{!}} {{{внизу}}} }} |}<noinclude>{{doc}}</noinclude> 87d436c1491fb07718a7bb1c6ab4849dead4626f Шаблон:Родственный проект/styles.css 10 288 738 737 2024-08-26T16:46:03Z DuOfOrl 5 1 версия импортирована sanitized-css text/css .ts-Родственный_проект, .ts-Родственный_проект.metadata:not(.notheme) { background: var(--background-color-neutral-subtle, #f8f9fa); border: 1px solid var(--border-color-base, #a2a9b1); clear: right; float: right; font-size: 90%; margin: 0 0 1em 1em; padding: .4em; max-width: 19em; width: 19em; line-height: 1.5; } .ts-Родственный_проект th, .ts-Родственный_проект td { padding: .2em 0; vertical-align: middle; } .ts-Родственный_проект th + td { padding-left: .4em; } @media (max-width: 719px) { .ts-Родственный_проект { width: auto; margin-left: 0; margin-right: 0; } } /* [[Категория:Шаблоны:Подстраницы CSS]] */ 50b08ba20d75d9b717bc6920475793f259cd3af1 Шаблон:Орден Красного Знамени 10 289 740 739 2024-08-26T16:46:03Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{#switch: {{{тип|}}} | воинская часть = [[Файл:Order of Red Banner.svg|34px|link=Орден Красного Знамени|Орден Красного Знамени {{#if: {{{1|}}} |  — {{{1}}} }}]]{{#if: {{NAMESPACE}}{{{nocat|}}} || [[Категория:Воинские части, награждённые орденом Красного Знамени]] }} | город = [[Файл:Order of Red Banner.svg|34px|link=Орден Красного Знамени|Орден Красного Знамени{{#if: {{{1|}}} |  — {{{1}}} }}]]{{#if: {{NAMESPACE}}{{{nocat|}}} || [[Категория:Города, награждённые орденом Красного Знамени]] }} | регион = [[Файл:Order of Red Banner.svg|34px|link=Орден Красного Знамени|Орден Красного Знамени{{#if: {{{1|}}} |  — {{{1}}} }}]]{{#if: {{NAMESPACE}}{{{nocat|}}} || [[Категория:Регионы, награждённые орденом Красного Знамени]] }} | организация = [[Файл:Order of Red Banner.svg|34px|link=Орден Красного Знамени|Орден Красного Знамени{{#if: {{{1|}}} |  — {{{1}}} }}]]{{#if: {{NAMESPACE}}{{{nocat|}}} || [[Категория:Организации, награждённые орденом Красного Знамени]] }} | СМИ | сми = [[Файл:Order of Red Banner.svg|34px|link=Орден Красного Знамени|Орден Красного Знамени {{#if: {{{1|}}} | — {{{1}}} }}]]{{#if: {{NAMESPACE}}{{{nocat|}}} || [[Категория:СМИ, награждённые орденом Красного Знамени]] }} | корабль = [[Файл:Order of Red Banner.svg|34px|link=Орден Красного Знамени|Орден Красного Знамени{{#if: {{{1|}}} | — {{{1}}} }}]]{{#if: {{NAMESPACE}}{{{nocat|}}} || [[Категория:Корабли, награждённые орденом Красного Знамени]] }} | [[Файл:SU Order of the Red Banner ribbon.svg|40px|link=Орден Красного Знамени|Орден Красного Знамени {{#if: {{{1|}}} |  — {{{1}}} }}]]{{#if: {{NAMESPACE}}{{{nocat|}}} || [[Категория:Кавалеры ордена Красного Знамени]] }} }}<noinclude> {{doc}} </noinclude> a4b6026ef99495ca5077c93a9192ac2427bbb09e Шаблон:Ряд 10 290 742 741 2024-08-26T16:46:05Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <templatestyles src="Шаблон:Ряд/styles.css" /><table role="presentation" class="infobox-inherit ts-Ряд {{#switch:{{{выровнять|}}} | влево = pull-left | вправо = pull-right | по ширине = pull-justify | #default = pull-center}}"><tr>{{ #if:{{{1|}}}|<td>{{{1}}}</td>}}{{ #if:{{{2|}}}|<td>{{{2}}}</td>}}{{ #if:{{{3|}}}|<td>{{{3}}}</td>}}{{ #if:{{{4|}}}|<td>{{{4}}}</td>}}{{ #if:{{{5|}}}|<td>{{{5}}}</td>}}{{ #if:{{{6|}}}|<td>{{{6}}}</td>}}{{ #if:{{{7|}}}|<td>{{{7}}}</td>}}{{ #if:{{{8|}}}|<td>{{{8}}}</td>}}{{ #if:{{{9|}}}|<td>{{{9}}}</td>}}{{ #if:{{{10|}}}|<td>{{{10}}}</td>}} </tr></table><noinclude>{{doc}}</noinclude> 387ead03289de2d203805d43b37873225d7eaa75 Шаблон:Ряд/styles.css 10 291 744 743 2024-08-26T16:46:06Z DuOfOrl 5 1 версия импортирована sanitized-css text/css .ts-Ряд { width: auto; border-collapse: collapse; } .ts-Ряд td { padding-right: 2px; padding-left: 2px; text-align: center; } .ts-Ряд td:first-child { padding-left: 0; text-align: left; } .ts-Ряд td:last-child { padding-right: 0; text-align:right; } .ts-Ряд.pull-left { } .ts-Ряд.pull-center { margin: 0 auto !important; } .ts-Ряд.pull-right { clear: right; margin: 0 0 0 auto !important; } .ts-Ряд.pull-justify { width: 100%; } body.skin-minerva .ts-Ряд { display: table; } body.skin-minerva .ts-Ряд td { padding: 2px; } body.skin-minerva .ts-Ряд:not(.pull-justify) { width: auto !important; } /* [[Категория:Шаблоны:Подстраницы CSS]] */ 2229c228f5137296027e241d85449ea3d3a02656 Шаблон:Вложенные кавычки 10 292 746 745 2024-08-26T16:46:07Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{replace | {{#invoke:string|replace<!-- -->| {{#invoke:string|replace<!-- -->| {{#invoke:string|replace<!-- -->| {{#invoke:string|replace<!-- -->| {{{1|}}} | pattern = %[%[(.?[^%]{{!}}]-)«(.[^«»]-)»(.?[^%]{{!}}]-){{!}} | replace = {{хх}}%1<<%2>>%3{{!}} | plain = false<!-- -->}} | pattern = %[%[(.?[^%]{{!}}]-)«(.[^«»]-)»(.?[^%[{{!}}]-)%]%] | replace = [[%1<<%2>>%3{{!}}%1«%2»%3]] | plain = false<!-- -->}} | pattern = «(.[^«»]-)» | replace = „%1“ | plain = false<!-- -->}} | pattern = <<(.[^<>]-)>> | replace = «%1» | plain = false<!-- -->}}}}<noinclude>{{doc}}</noinclude> 48611a5cc8c8ac357e4b2a083c1845c15462160e Шаблон:Учёная степень 10 293 748 747 2024-08-26T16:46:08Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <includeonly>{{#switch: {{{1|}}} | кандидат = {{#switch: {{{2|}}} | архитектуры = [[кандидат архитектуры]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты архитектуры]]}} | биологических наук = [[кандидат биологических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты биологических наук]]}} | ветеринарных наук = [[кандидат ветеринарных наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты ветеринарных наук]]}} | военно-морских наук = [[кандидат военно-морских наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты военно-морских наук]]}} | военных наук = [[кандидат военных наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты военных наук]]}} | географических наук = [[кандидат географических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты географических наук]]}} | геолого-минералогических наук = [[кандидат геолого-минералогических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты геолого-минералогических наук]]}} | искусствоведения = [[кандидат искусствоведения]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты искусствоведения]]}} | исторических наук = [[кандидат исторических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты исторических наук]]}} | культурологии = [[кандидат культурологии]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты культурологии]]}} | медицинских наук = [[кандидат медицинских наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты медицинских наук]]}} | педагогических наук = [[кандидат педагогических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты педагогических наук]]}} | политических наук = [[кандидат политических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты политических наук]]}} | психологических наук = [[кандидат психологических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты психологических наук]]}} | сельскохозяйственных наук = [[кандидат сельскохозяйственных наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты сельскохозяйственных наук]]}} | социологических наук = [[кандидат социологических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты социологических наук]]}} | технических наук = [[кандидат технических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты технических наук]]}} | фармацевтических наук = [[кандидат фармацевтических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты фармацевтических наук]]}} | физико-математических наук = [[кандидат физико-математических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты физико-математических наук]]}} | филологических наук = [[кандидат филологических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты филологических наук]]}} | философских наук = [[кандидат философских наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты философских наук]]}} | химических наук = [[кандидат химических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты химических наук]]}} | экономических наук = [[кандидат экономических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты экономических наук]][[Категория:Учёные по алфавиту]][[Категория:Экономисты по алфавиту]]}} | юридических наук = [[кандидат юридических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты юридических наук]]}} | [[кандидат наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты наук]]}} }} | доктор = {{#switch: {{{2|}}} | архитектуры = [[доктор архитектуры]]{{#if:{{NAMESPACE}}||[[Категория:Доктора архитектуры]]}} | биологических наук = [[доктор биологических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора биологических наук]]}} | ветеринарных наук = [[доктор ветеринарных наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора ветеринарных наук]]}} | военно-морских наук = [[доктор военно-морских наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора военно-морских наук]]}} | военных наук = [[доктор военных наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора военных наук]]}} | географических наук = [[доктор географических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора географических наук]]}} | геолого-минералогических наук = [[доктор геолого-минералогических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора геолого-минералогических наук]]}} | искусствоведения = [[доктор искусствоведения]]{{#if:{{NAMESPACE}}||[[Категория:Доктора искусствоведения]]}} | исторических наук = [[доктор исторических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора исторических наук]]}} | культурологии = [[доктор культурологии]]{{#if:{{NAMESPACE}}||[[Категория:Доктора культурологии]]}} | медицинских наук = [[доктор медицинских наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора медицинских наук]]}} | педагогических наук = [[доктор педагогических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора педагогических наук]]}} | политических наук = [[доктор политических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора политических наук]]}} | психологических наук = [[доктор психологических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора психологических наук]]}} | сельскохозяйственных наук = [[доктор сельскохозяйственных наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора сельскохозяйственных наук]]}} | социологических наук = [[доктор социологических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора социологических наук]]}} | технических наук = [[доктор технических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора технических наук]]}} | фармацевтических наук = [[доктор фармацевтических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора фармацевтических наук]]}} | физико-математических наук = [[доктор физико-математических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора физико-математических наук]]}} | филологических наук = [[доктор филологических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора филологических наук]]}} | философских наук = [[доктор философских наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора философских наук]]}} | химических наук = [[доктор химических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора химических наук]]}} | экономических наук = [[доктор экономических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора экономических наук]][[Категория:Учёные по алфавиту]][[Категория:Экономисты по алфавиту]]}} | юридических наук = [[доктор юридических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора юридических наук]]}} | [[доктор наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора наук]]}} }} }}</includeonly><noinclude>{{doc}}</noinclude> 21fc4a364f53264639c70cc9807f6963ccb36b53 Шаблон:Орден Октябрьской Революции 10 294 750 749 2024-08-26T16:46:08Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{#switch: {{{тип|}}} | воинская часть = [[Файл:Order of the October Revolution.svg|45px|link=Орден Октябрьской Революции|Орден Октябрьской Революции {{#if: {{{1|}}}| — {{{1}}}}}]]{{#if:{{NAMESPACE}}{{{nocat|}}}||[[Категория:Воинские части, награждённые орденом Октябрьской Революции]]}} | город = [[Файл:Order of the October Revolution.svg|45px|link=Орден Октябрьской Революции|Орден Октябрьской Революции {{#if: {{{1|}}}| — {{{1}}}}}]]{{#if:{{NAMESPACE}}{{{nocat|}}}||[[Категория:Города, награждённые орденом Октябрьской Революции]]}} | регион = [[Файл:Order of the October Revolution.svg|45px|link=Орден Октябрьской Революции|Орден Октябрьской Революции {{#if: {{{1|}}}| — {{{1}}}}}]]{{#if:{{NAMESPACE}}{{{nocat|}}}||[[Категория:Регионы, награждённые орденом Октябрьской Революции]]}} | организация = [[Файл:Order of the October Revolution.svg|45px|link=Орден Октябрьской Революции|Орден Октябрьской Революции {{#if: {{{1|}}}| — {{{1}}}}}]]{{#if:{{NAMESPACE}}{{{nocat|}}}||[[Категория:Организации, награждённые орденом Октябрьской Революции]]}} | СМИ | сми = [[Файл:Order of the October Revolution.svg|45px|link=Орден Октябрьской Революции|Орден Октябрьской Революции {{#if: {{{1|}}}|— {{{1}}}}}]]{{#if:{{NAMESPACE}}{{{nocat|}}}||[[Категория:СМИ, награждённые орденом Октябрьской Революции]]}} | корабль = [[Файл:Order of the October Revolution.svg|45px|link=Орден Октябрьской Революции|Орден Октябрьской Революции {{#if: {{{1|}}}| — {{{1}}}}}]]{{#if:{{NAMESPACE}}{{{nocat|}}}||[[Категория:Корабли, награждённые орденом Октябрьской Революции]]}} | [[Файл:SU Order of the October Revolution ribbon.svg|40px|link=Орден Октябрьской Революции|Орден Октябрьской Революции {{#if: {{{1|}}}| — {{{1}}}}}]]{{#if:{{NAMESPACE}}{{{nocat|}}}||[[Категория:Кавалеры ордена Октябрьской Революции]]}} }}<noinclude> {{doc}} </noinclude> c58fd2bbb6f2eea7bf65e4206a596693f9307c98 Шаблон:Учёное звание 10 295 752 751 2024-08-26T16:46:09Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki <includeonly>{{#switch: {{{1|}}} <!-- современная Россия --> | РАН = {{#switch: {{{2|}}}| 1 = [[Члены-корреспонденты РАН|член-корреспондент РАН]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты РАН]]}}| 0 = [[Действительные члены РАН|академик РАН]]{{#if:{{NAMESPACE}}||[[Категория:Действительные члены РАН]]}}|<!--пустое значение-->}} <!-- Российская академия наук --> | РАМН = {{#switch: {{{2|}}}| 1 = [[Члены-корреспонденты РАМН|член-корреспондент РАМН]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты РАМН]]}}| 0 = [[Российская академия медицинских наук|академик РАМН]]{{#if:{{NAMESPACE}}||[[Категория:Академики РАМН]]}}|<!--пустое значение-->}} <!-- Российская академия медицинских наук --> | РАО = {{#switch: {{{2|}}}| 1 = [[Российская академия образования|член-корреспондент РАО]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты РАО]]}}| 0 = [[Действительные члены (академики) Российской академии образования|академик РАО]]{{#if:{{NAMESPACE}}||[[Категория:Академики РАО]]}}|<!--пустое значение-->}} <!-- Российская академия образования --> | РАСХН = {{#switch: {{{2|}}}| 1 = [[Российская академия сельскохозяйственных наук|член-корреспондент РАСХН]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты РАСХН]]}}| 0 = [[Российская академия сельскохозяйственных наук|академик РАСХН]]{{#if:{{NAMESPACE}}||[[Категория:Академики РАСХН]]}}|<!--пустое значение-->}} <!-- Российская академия сельскохозяйственных наук --> | РААСН = {{#switch: {{{2|}}}| 1 = [[Члены-корреспонденты Российской академии архитектуры и строительных наук|член-корреспондент РААСН]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты РААСН]]}}| 0 = [[Академики Российской академии архитектуры и строительных наук|академик РААСН]]{{#if:{{NAMESPACE}}||[[Категория:Академики РААСН]]}}|<!--пустое значение-->}} <!-- Российская академия архитектуры и строительных наук --> | РАХ = {{#switch: {{{2|}}}| 1 = [[Российская академия художеств|член-корреспондент РАХ]]<br />{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты РАХ]]}}| 0 = [[Список действительных членов РАХ|академик РАХ]] {{#if:{{NAMESPACE}}||[[Категория:Действительные члены РАХ]]}}|<!--пустое значение-->}} <!-- Российская академия художеств --> <!-- СССР --> | АН СССР = {{#switch: {{{2|}}}| 1 = [[Члены-корреспонденты РАН за всю историю существования|член-корреспондент АН СССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН СССР]]}}| 0 = [[Академики АН СССР|академик АН СССР]]{{#if:{{NAMESPACE}}||[[Категория:Действительные члены АН СССР]]}}|<!--пустое значение-->}} <!-- Академия наук СССР --> | АМН СССР = {{#switch: {{{2|}}}| 1 = [[Академия медицинских наук СССР|член-корреспондент АМН СССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АМН СССР]]}}| 0 = [[Академия медицинских наук СССР|академик АМН СССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики АМН СССР]]}}|<!--пустое значение-->}} <!-- Академия медицинских наук СССР (1944—1992) --> | АПН СССР = {{#switch: {{{2|}}}| 1 = [[Российская академия образования|член-корреспондент АПН СССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АПН СССР]]}}| 0 = [[Российская академия образования|академик АПН СССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики АПН СССР]]}}|<!--пустое значение-->}} <!-- Академия педагогических наук СССР (1966—1992) --> | ВАСХНИЛ = {{#switch: {{{2|}}}| 1 = [[Список членов-корреспондентов ВАСХНИЛ и РАСХН|член-корреспондент ВАСХНИЛ]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты ВАСХНИЛ]]}}| 0 = [[Всесоюзная академия сельскохозяйственных наук имени Ленина|академик ВАСХНИЛ]]{{#if:{{NAMESPACE}}||[[Категория:Академики ВАСХНИЛ]]}}|<!--пустое значение-->}} <!-- ВАСХНИЛ (1929—1992) --> | АА СССР = {{#switch: {{{2|}}}| 1 = [[Российская академия архитектуры и строительных наук|член-корреспондент АА СССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АА СССР]]}}| 0 = [[Российская академия архитектуры и строительных наук|академик АА СССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики Академии архитектуры СССР]]}}|<!--пустое значение-->}} <!-- Академия архитектуры СССР (1934—1956) и Академия строительства и архитектуры СССР (1956—1964) --> | АХ СССР = {{#switch: {{{2|}}}| 1 = [[Академия художеств СССР|член-корреспондент АХ СССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты Академии художеств СССР]]}}| 0 = [[Академия художеств СССР|академик АХ СССР]]{{#if:{{NAMESPACE}}||[[Категория:Действительные члены Академии художеств СССР]]}}|<!--пустое значение-->}} <!-- Академия художеств СССР республики ССР --> | АН АзССР = {{#switch: {{{2|}}}| 1 = [[Национальная академия наук Азербайджана|член-корреспондент АН Азербайджанской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН Азербайджанской ССР]]}}| 0 = [[Национальная академия наук Азербайджана|академик АН Азербайджанской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики АН Азербайджанской ССР]]}}|<!--пустое значение-->}} <!-- Академия наук Азербайджанской ССР --> | АН АрмССР = {{#switch: {{{2|}}}| 1 = [[Национальная академия наук Республики Армения|член-корреспондент АН Армянской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН Армянской ССР]]}}| 0 = [[Действительные члены НАН Армении за всю историю существования|академик АН Армянской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики АН Армянской ССР]]}}|<!--пустое значение-->}} <!-- Академия наук Армянской ССР --> | АН БССР = {{#switch: {{{2|}}}| 1 = [[Национальная академия наук Беларуси|член-корреспондент АН БССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты Академии наук Белорусской ССР]]}}| 0 = [[Национальная академия наук Беларуси|академик АН БССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики Академии наук Белорусской ССР]]}}|<!--пустое значение-->}} <!-- Белорусская академия наук в 1928-1936 гг.; Академия наук Белорусской ССР в 1936-1991 гг. --> | АН ГрузССР = {{#switch: {{{2|}}}| 1 = [[Национальная академия наук Грузии|член-корреспондент АН Грузинской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН Грузинской ССР‎]]}}| 0 = [[Национальная академия наук Грузии|академик АН Грузинской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики АН Грузинской ССР]]}}|<!--пустое значение-->}} <!-- Академия наук Грузинской ССР --> | АН МССР = {{#switch: {{{2|}}}| 1 = [[Академия наук Молдавии|член-корреспондент АН МССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН Молдавской ССР]]}}| 0 = [[Академия наук Молдавии|академик АН МССР]]{{#if:{{NAMESPACE}}||[[Категория:Действительные члены Академии наук Молдавской ССР]]}}|<!--пустое значение-->}} <!-- Академия наук Молдавской ССР --> | АН КазССР = {{#switch: {{{2|}}}| 1 = [[Национальная академия наук Казахстана|член-корреспондент АН Казахской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН Казахской ССР]]}}| 0 = [[Национальная академия наук Казахстана|академик АН Казахской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики АН Казахской ССР]]}}|<!--пустое значение-->}} <!-- Академия наук Казахской ССР --> | АН КиргССР = {{#switch: {{{2|}}}| 1 = [[Национальная академия наук Кыргызской Республики|член-корреспондент АН Киргизской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН Киргизской ССР]]}}| 0 = [[Национальная академия наук Кыргызской Республики|академик АН Киргизской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики АН Киргизской ССР]]}}|<!--пустое значение-->}} <!-- Академия наук Киргизской ССР --> | АН ЛатССР = {{#switch: {{{2|}}}| 1 = [[Академия наук Латвии|член-корреспондент АН Латвийской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН Латвийской ССР]]}}| 0 = [[Академия наук Латвии|академик АН Латвийской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики АН Латвийской ССР]]}}|<!--пустое значение-->}} <!-- Академия наук Латвийской ССР --> | АН ЛитССР = {{#switch: {{{2|}}}| 1 = [[Академия наук Литвы|член-корреспондент АН Литовской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН Литовской ССР]]}}| 0 = [[Академия наук Литвы|академик АН Литовской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики АН Литовской ССР]]}}|<!--пустое значение-->}} <!-- Академия наук Литовской ССР --> | АН УзССР = {{#switch: {{{2|}}}| 1 = [[Академия наук Узбекистана|член-корреспондент АН Узбекской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН Узбекской ССР]]}}| 0 = [[Академия наук Узбекистана|академик АН Узбекской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики АН Узбекской ССР]]}}|<!--пустое значение-->}} <!-- Академия наук Узбекской ССР --> | АН УССР = {{#switch: {{{2|}}}| 1 = [[Национальная академия наук Украины|член-корреспондент АН УССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН УССР]]}}| 0 = [[Национальная академия наук Украины|академик АН УССР]]{{#if:{{NAMESPACE}}||[[Категория:Действительные члены АН УССР]]}}|<!--пустое значение-->}}<!-- Академия наук Украинской ССР --> | АН ЭССР = {{#switch: {{{2|}}}| 1 = [[Эстонская академия наук|член-корреспондент АН ЭССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН Эстонской ССР]]}}| 0 = [[Эстонская академия наук|академик АН ЭССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики АН Эстонской ССР]]}}|<!--пустое значение-->}} <!-- Академия наук Эстонской ССР --> | АПН РСФСР = {{#switch: {{{2|}}}| 1 = [[Российская академия образования|член-корреспондент АПН РСФСР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АПН РСФСР]]}}| 0 = [[Российская академия образования|действительный член АПН РСФСР]]{{#if:{{NAMESPACE}}||[[Категория:Академики АПН РСФСР]]}}|<!--пустое значение-->}} <!-- Академия педагогических наук РСФСР --> | АН ТаджССР = {{#switch: {{{2|}}}| 1 = [[Академия наук Республики Таджикистан|член-корреспондент АН Таджикской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН Таджикской ССР]]}}| 0 = [[Академия наук Республики Таджикистан|действительный член АН Таджикской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики АН Таджикской ССР]]}}|<!--пустое значение-->}} <!-- Академия наук Таджикской ССР --> | АН ТуркССР = {{#switch: {{{2|}}}| 1 = [[Академия наук Туркмении|член-корреспондент АН Туркменской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН Туркменской ССР]]}}| 0 = [[Академия наук Туркмении|действительный член АН Туркменской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики АН Туркменской ССР]]}}|<!--пустое значение-->}} <!-- Академия наук Туркменской ССР --> <!-- постсоветские страны --> | НАНБ | АНБ = {{#switch: {{{2|}}}| 1 = [[Национальная академия наук Беларуси|член-корреспондент НАНБ]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты Национальной академии наук Беларуси]]}}| 0 = [[Национальная академия наук Беларуси|академик НАНБ]]{{#if:{{NAMESPACE}}||[[Категория:Академики Национальной академии наук Беларуси]]}}|<!--пустое значение-->}} <!-- Академия наук Беларуси в 1991—1997 гг (АНБ); Национальная академия наук Беларуси (НАН Беларуси, или НАНБ) с 1997 --> | АНМ = {{#switch: {{{2|}}}| 1 = [[Академия наук Молдавии|член-корреспондент АНМ]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АНМ]]}}| 0 = [[Академия наук Молдавии|академик АНМ]]{{#if:{{NAMESPACE}}||[[Категория:Академики Молдовы]]}}|<!--пустое значение-->}} | ААНБ = {{#switch: {{{2|}}}| 1 = [[Академия аграрных наук Беларуси|член-корреспондент ААНБ]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты ААНБ]]}}| 0 = [[Академия аграрных наук Беларуси|академик ААНБ]]{{#if:{{NAMESPACE}}||[[Категория:Академики ААНБ]]}}|<!--пустое значение-->}} <!-- Академия аграрных наук Беларуси (ААН Беларуси) --> | НАН РК = {{#switch: {{{2|}}}| 1 = [[Национальная академия наук Казахстана|член-корреспондент НАН РК]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты НАН Казахстана]]}}| 0 = [[Национальная академия наук Казахстана|академик НАН РК]]{{#if:{{NAMESPACE}}||[[Категория:Академики НАН Казахстана]]}}|<!--пустое значение-->}} <!-- Академия наук Казахстана --> | НАН КР = {{#switch: {{{2|}}}| 1 = [[Национальная академия наук Кыргызской Республики|член-корреспондент НАН КР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты НАН Кыргызстана]]}}| 0 = [[Национальная академия наук Кыргызской Республики|академик НАН КР]]{{#if:{{NAMESPACE}}||[[Категория:Академики НАН Кыргызстана]]}}|<!--пустое значение-->}} <!-- Академия наук Кыргызстана--> | НАН РА = {{#switch: {{{2|}}}| 1 = [[Национальная академия наук Республики Армения|член-корреспондент НАН РА]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты НАН Армении]]}}| 0 = [[Действительные члены НАН Армении за всю историю существования|академик НАН РА]]{{#if:{{NAMESPACE}}||[[Категория:Академики НАН Армении]]}}|<!--пустое значение-->}} <!-- Национальная академия наук Армении --> | НАНА = {{#switch: {{{2|}}}| 1 = [[Национальная академия наук Азербайджана|член-корреспондент НАНА]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты НАН Азербайджана]]}}| 0 = [[Национальная академия наук Азербайджана|академик НАНА]]{{#if:{{NAMESPACE}}||[[Категория:Академики НАН Азербайджана]]}}|<!--пустое значение-->}} <!-- Национальная академия наук Азербайджана --> | НАНУ = {{#switch: {{{2|}}}| 1 = [[Национальная академия наук Украины|член-корреспондент НАНУ]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты НАН Украины]]}}| 0 = [[Национальная академия наук Украины|академик НАНУ]]{{#if:{{NAMESPACE}}||[[Категория:Действительные члены НАН Украины]]}}|<!--пустое значение-->}} <!-- Национальная академия наук Украины --> | НАМНУ = {{#switch: {{{2|}}}| 1 = [[Национальная академия медицинских наук Украины|член-корреспондент НАМНУ]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты Национальной академии медицинских наук Украины]]}}| 0 = [[Национальная академия медицинских наук Украины|академик НАМНУ]]{{#if:{{NAMESPACE}}||[[Категория:Академики Национальной академии медицинских наук Украины]]}}|<!--пустое значение-->}} <!-- Национальная академия медицинских наук Украины --> | СПбАН = {{#switch: {{{2|}}}| 1 = [[Петербургская академия наук|член-корреспондент СПбАН]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты Петербургской академии наук]]}}| 0 = [[Петербургская академия наук|академик СПбАН]]{{#if:{{NAMESPACE}}||[[Категория:Действительные члены Петербургской академии наук]]}}|<!--пустое значение-->}} <!-- Петербургская академия наук --> | ПАН = {{#switch: {{{2|}}}| 1 = [[Польская академия наук|член-корреспондент ПАН]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты Польской академии наук]]}}| 0 = [[Польская академия наук|действительный член ПАН]]{{#if:{{NAMESPACE}}||[[Категория:Действительные члены Польской академии наук]]}}| 2 = [[Польская академия наук|иностранный член ПАН]]{{#if:{{NAMESPACE}}||[[Категория:Иностранные члены Польской академии наук‎]]}}| 3 = [[Польская академия наук|сотрудник ПАН]]{{#if:{{NAMESPACE}}||[[Категория:Сотрудники Польской академии наук‎]]}}|<!--пустое значение-->}} <!-- Польская академия наук --> | НАПНУ = {{#switch: {{{2|}}}| 1 = [[Национальная академия педагогических наук Украины|член-корреспондент НАПНУ]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты Национальной академии педагогических наук Украины]]}}| 0 = [[Национальная академия педагогических наук Украины|действительный член НАПНУ]]{{#if:{{NAMESPACE}}||[[Категория:Академики Национальной академии педагогических наук Украины]]}}|<!--пустое значение-->}} <!-- Национальная академия педагогических наук Украины --> | НАПрНУ = {{#switch: {{{2|}}}| 1 = [[Национальная академия правовых наук Украины|член-корреспондент НАПрНУ]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты Национальной академии правовых наук Украины]]}}| 0 = [[Национальная академия правовых наук Украины|действительный член НАПрНУ]]{{#if:{{NAMESPACE}}||[[Категория:Академики Национальной академии правовых наук Украины]]}}|<!--пустое значение-->}} <!-- Национальная академия правовых наук Украины --> | НАН Грузии = {{#switch: {{{2|}}}| 1 = [[Национальная академия наук Грузии|член-корреспондент НАН Грузии]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты Академии наук Грузии]]}}| 0 = [[Национальная академия наук Грузии|действительный член НАН Грузии]]{{#if:{{NAMESPACE}}||[[Категория:Академики Академии наук Грузии‎]]}}|<!--пустое значение-->}} <!-- Национальная академия наук Грузии--> | АН Узбекистана = {{#switch: {{{2|}}}| 1 = [[Академия наук Узбекистана|член-корреспондент АН Узбекистана]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН Узбекистана]]}}| 0 = [[Академия наук Узбекистана|действительный член АН Узбекистана]]{{#if:{{NAMESPACE}}||[[Категория:Академики АН Узбекистана]]}}|<!--пустое значение-->}} <!-- Академия наук Узбекистана --> <!-- Научное звание --> | {{#switch: {{{2|}}}| 1 = [[доцент]]| доцент = [[доцент]]| 0 = [[профессор (звание)|профессор]] | профессор = [[профессор (звание)|профессор]] |<!--пустое значение-->}} <!-- не академики --> }}</includeonly><noinclude>{{doc}}</noinclude> c96f56648a68c3a7ea133f232c7bf1196d3fa462 Шаблон:Установлена проверка на неизвестные параметры 10 296 754 753 2024-08-26T16:46:10Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{ombox |name = Установлена проверка на неизвестные параметры |text = В этом шаблоне установлена [[Модуль:Check for unknown parameters|проверка на неизвестные параметры]], добавляющая страницы в {{c|{{#if:{{{категория|}}}|{{{категория|}}}|Страницы с неизвестными параметрами шаблона {{ROOTPAGENAME}}}}|В}}. |type = notice }}<includeonly>{{no-doc|[[Категория:Шаблоны с установленной проверкой на неизвестные параметры]]{{#ifexist: Категория:{{#if:{{{категория|}}}|{{{категория|}}}|Страницы с неизвестными параметрами шаблона {{ROOTPAGENAME}}}} || [[Категория:Шаблоны с установленной проверкой на неизвестные параметры и несуществующей категорией]] }}|nocat={{{nocat|}}}}}</includeonly><noinclude>{{doc-inline}} См. [[Модуль:Check for unknown parameters]] и [[:Категория:Википедия:Неизвестные параметры шаблонов]]. Добавляет {{Категория с размером|Шаблоны с установленной проверкой на неизвестные параметры и несуществующей категорией}}. [[Категория:Шаблоны:Предупреждения]] [[Категория:Шаблоны:Для документирования шаблонов]] {{doc-end}} </noinclude> cd47e06eec53b65393adba1f3143d6cd3d6cc54c Шаблон:C 10 297 756 755 2024-08-26T16:46:10Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{#switch: {{{2}}} | Р = {{{к|к}}}атегории | Д = {{{к|к}}}атегории | В = {{{к|к}}}атегорию | Т = {{{к|к}}}атегорией | П = {{{к|к}}}атегории | ю = {{{к|к}}}атегорию | ей | й = {{{к|к}}}атегорией | и = {{{к|к}}}атегории | {{{к|к}}}атегория }} «[[:Категория:{{{1}}}|{{вложенные кавычки|{{{1}}}}}]]»<noinclude>{{doc}}</noinclude> 29dc241d0737db87ea05ae164b21b3bdc0da3f83 Шаблон:Заготовка шаблона 10 298 758 757 2024-08-26T16:46:12Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{#invoke:TemplateDataDoc|generateBlank|{{#if:{{{1|}}}|{{{1}}}|{{BASEPAGENAME}}}}|description={{{описание|}}}}}<noinclude>{{doc}}</noinclude> b451404244fd6898bc134564ddcb8941eca7f64a Модуль:TemplateDataDoc 828 299 760 759 2024-08-26T16:46:12Z DuOfOrl 5 1 версия импортирована Scribunto text/plain require( 'strict' ); local docSubPage = mw.message.new( 'Templatedata-doc-subpage' ):plain(); local p = {}; local lastNumber = 0; -- Enable/disable additional spacing for block-formatted templates local formatBlockSpaces = true; -- Params that should not be shown in code local deprecatedParams = { 'nocat', 'from', 'nocoord', 'nocatcoord', 'Автооформление заголовка', 'автооформление заголовка', 'Ширина', 'ширина', 'Ширина изображения', 'ширина изображения', 'Ширина логотипа', 'ширина логотипа', 'Ширина автографа', 'ширина автографа', }; local noDocNote = 'TemplateDataDoc: Запишите страницу для отображения заполненного шаблона.'; function p.processJson( json ) local status, data = pcall( mw.text.jsonDecode, json ); if status == false then return nil; end if not data[ 'paramOrder' ] then data[ 'paramOrder' ] = {}; for paramName, paramData in pairs( data[ 'params' ] ) do table.insert( data[ 'paramOrder' ], paramName ); end end for _, param in ipairs( deprecatedParams ) do if data[ 'params' ][ param ] ~= nil then data[ 'params' ][ param ][ 'deprecated' ] = '-'; end end return data; end function p.getTemplateData( pageName ) local title = mw.title.makeTitle( 0, pageName ); if not title or not title.exists then return false end local content = title:getContent() if not content then return false; end; local json = mw.ustring.match( content, '<[Tt]emplate[Dd]ata%s*>(.*)</[Tt]emplate[Dd]ata%s*>' ); if not json then return nil; end return p.processJson( json ) end function p.getValue( data, key ) if data[ key ] then return data[ key ]; end -- Numbered keys return as numbers local nkey = tonumber( key ); if nkey ~= nil and data[ nkey ] then return data[ nkey ]; end return {}; end -- See https://phabricator.wikimedia.org/diffusion/ETDA/browse/master/Specification.md?as=remarkup -- We need a global format value for the 'block' and 'inline': [[phab:T205438]] function p.convertFormatString( rawTemplateFormat ) local formatType = rawTemplateFormat or 'inline'; local templateFormat = formatType; local isBlockFormatted = false; if formatType == 'block' then templateFormat = '{{_\n| _ = _\n}}'; isBlockFormatted = true; elseif formatType == 'inline' then templateFormat = '{{_|_=_}}'; end return templateFormat, isBlockFormatted, formatType; end function p.getFormatParts( rawTemplateFormat, templateName ) local templateFormat, isBlockFormatted, formatType = p.convertFormatString( rawTemplateFormat ); local nameFormat = mw.ustring.match( templateFormat, '^[^|]+' ); local paramKeyFormat = mw.ustring.match( templateFormat, '%|[^=]+=' ); local paramValueFormat = mw.ustring.match( templateFormat, '=[^}]+' ); paramValueFormat = mw.ustring.sub( paramValueFormat, 2 ); local endFormat = mw.ustring.match( templateFormat, '%}%}.*$' ); local startFormat = mw.ustring.gsub( nameFormat, '_', templateName ); return isBlockFormatted, formatType, startFormat, endFormat, paramKeyFormat, paramValueFormat; end function p.formatKeyValue( key, parameterData, formatData ) if parameterData[ 'deprecated' ] then return ''; end local args = formatData.args; local parameterName = key; local nkey = tonumber( key ); -- Add additional spacing to string keys if formatBlockSpaces and formatData.parameterLength and formatData.formatType ~= 'inline' and ( nkey == nil or lastNumber ~= nkey - 1 ) then while mw.ustring.len( key ) < formatData.parameterLength do key = key .. ' '; end end -- Remove numbering for adjacent numbered keys if nkey ~= nil and lastNumber == nkey - 1 then key = ''; lastNumber = nkey; end local value = ''; if formatData.valueKey == 'example' and parameterData[ 'example' ] then -- Example value = parameterData[ 'example' ]; else if formatData.valueKey == 'description' and parameterData[ 'description' ] then -- Description value = parameterData[ 'description' ]; if value ~= '' then value = '&lt;!-- ' .. value .. ' --&gt;'; end elseif parameterData[ 'autovalue' ] then -- Autovalue value = parameterData[ 'autovalue' ]; end if args[ '$' .. parameterName ] and args[ '$' .. parameterName ] ~= '' then -- Custom values from template call value = args[ '$' .. parameterName ]; end end local formattedKey = mw.ustring.gsub( formatData.paramKeyFormat, '_+', key, 1 ); if key == '' then formattedKey = mw.ustring.gsub( formattedKey, '=', '' ); end return formattedKey .. mw.ustring.gsub( formatData.paramValueFormat, '_', value, 1 ); end function p.generateBlankCode( templateData, templateName, args ) if templateData == false then return '{{' .. templateName .. '}}'; end local parameterLength = 0; for i, parameterName in ipairs( templateData[ 'paramOrder' ] ) do local parameterData = p.getValue( templateData[ 'params' ], parameterName ); if not parameterData[ 'deprecated' ] then local length = mw.ustring.len( parameterName ); if length > parameterLength then parameterLength = length; end end end local isBlockFormatted, formatType, startFormat, endFormat, paramKeyFormat, paramValueFormat = p.getFormatParts( templateData[ 'format' ], templateName ); local out = startFormat; lastNumber = 0; for i, parameterName in ipairs( templateData[ 'paramOrder' ] ) do local parameterData = p.getValue( templateData[ 'params' ], parameterName ); if parameterData[ 'inherits' ] then parameterData = p.getValue( templateData[ 'params' ], parameterData[ 'inherits' ] ); end out = out .. p.formatKeyValue( parameterName, parameterData, { args = args, valueKey = ( args[ 'description' ] and 'description' or nil ), formatType = formatType, isBlockFormatted = isBlockFormatted, parameterLength = parameterLength, paramKeyFormat = paramKeyFormat, paramValueFormat = paramValueFormat, } ); end return out .. endFormat; end function p.generateBlank( frame ) local frame = mw.getCurrentFrame(); local getArgs = require( 'Module:Arguments' ).getArgs; local args = getArgs( frame ); local templateName = frame.args[ 1 ]; table.remove( args, 1 ); local docPage = 'Template:' .. templateName .. '/' .. docSubPage; local templateData = p.getTemplateData( docPage ); local out = p.generateBlankCode( templateData, templateName, args ); local previewNote = '' if templateData == false and frame:preprocess('{{REVISIONID}}') == '' then previewNote = '<div class="warningbox">' .. noDocNote .. '</div>'; end return previewNote .. frame:extensionTag{ name = 'pre', content = out }; end function p.generateExampleCode( templateData, templateName, args ) if templateData == false then return '{{' .. templateName .. '}}'; end local parameterLength = 0; for i, parameterName in ipairs( templateData[ 'paramOrder' ] ) do local parameterData = p.getValue( templateData[ 'params' ], parameterName ); if parameterData[ 'example' ] and not parameterData[ 'deprecated' ] then local length = mw.ustring.len( parameterName ); if length > parameterLength then parameterLength = length; end end end local isBlockFormatted, formatType, startFormat, endFormat, paramKeyFormat, paramValueFormat = p.getFormatParts( templateData[ 'format' ], templateName ); local out = startFormat; lastNumber = 0; for i, parameterName in ipairs( templateData[ 'paramOrder' ] ) do local parameterData = p.getValue( templateData[ 'params' ], parameterName ); if parameterData[ 'inherits' ] then parameterData = p.getValue( templateData[ 'params' ], parameterData[ 'inherits' ] ); end if parameterData[ 'example' ] then out = out .. p.formatKeyValue( parameterName, parameterData, { args = args, valueKey = 'example', formatType = formatType, isBlockFormatted = isBlockFormatted, parameterLength = parameterLength, paramKeyFormat = paramKeyFormat, paramValueFormat = paramValueFormat, } ); end end return out .. endFormat; end function p.generateExample( frame ) local frame = mw.getCurrentFrame(); local args = frame.args; local templateName = frame.args[ 1 ]; local docPage = 'Template:' .. templateName .. '/' .. docSubPage; local templateData = p.getTemplateData( docPage ); local out = p.generateExampleCode( templateData, templateName, args ); local previewNote = '' if templateData == false and frame:preprocess('{{REVISIONID}}') == '' then previewNote = '<div class="warningbox">' .. noDocNote .. '</div>'; end return previewNote .. frame:preprocess( out ) .. frame:extensionTag{ name = 'pre', content = out }; end return p; 53670b81abac0bc22d720fbe984944dcd709da7c Шаблон:Пример шаблона 10 300 762 761 2024-08-26T16:46:13Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{#invoke:TemplateDataDoc|generateExample|{{#if:{{{1|}}}|{{{1}}}|{{BASEPAGENAME}}}}}}<noinclude>{{doc}}</noinclude> 4675b6574c5d274f0525e41569d31a0a4881168f Шаблон:Uses Wikidata 10 301 764 763 2024-08-26T16:46:14Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{Родственный проект | проект = викиданные | текст = Этот {{module other|модуль|шаблон}} использует {{#if: {{{раздел|{{{section|}}}}}} | Свойства [[Викиданные|Викиданных]]; детальней см. [[#{{{раздел|{{{section|}}}}}}|§&nbsp;{{{раздел|{{{section}}}}}}]]. | [[ВП:Викиданные{{!}}свойств{{#if:{{{2|}}}|а|о}} Викиданных]]: }} | внизу = {{#if: {{{раздел|{{{section|}}}}}} || <div class="plainlist"><ul>{{#invoke:Uses Wikidata|usesProperty}}</ul></div> }} }}<noinclude> {{doc}} </noinclude> 5d62bf72bc1eea3b38bb5a9cd82eecf54b02fe45 Шаблон:Старый-новый стиль,примечание 10 302 766 765 2024-08-26T16:46:14Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki В случае, если дата рождения/смерти в источниках приведена по [[Юлианский календарь|старому стилю]], рекомендуется указывать её по новому стилю, а после указать в скобках отличающуюся часть даты по старому стилю. Например, * «13.05.1801 (1)» будет отображено как [[13 мая|1 (13) мая]] [[1801 год|1801]]; * «12.06.1801 (31.05)» будет отображено как 31 мая ([[12 июня]]) [[1801 год|1801]]; * «12.01.1802 (31.12.1801)» будет отображено как 31 декабря 1801 ([[12 января]] [[1802 год|1802]]). При этом в статью будут автоматически подставлены категории даты рождения/смерти по ''новому'' стилю. Учтите, что разница между датами нового и старого стиля составляет 13 дней в XX и XXI веках, 12 дней в XIX веке, 11 дней в XVIII веке, 10 дней в XVII и XVI веках (начиная с 5 (15) октября 1582 года).<noinclude>{{doc-inline}}Шаблон предназначен для подстановки в качестве примечания к полям «дата рождения», «дата смерти» для страниц документации шаблонов-карточек типа «Персона». Параметров не принимает. Вызов: {{tl|Старый-новый стиль,примечание}} {{doc-end}} [[Категория:Википедия:Шаблоны, встраиваемые в шаблоны-карточки:Личности]] </noinclude> 7f8754eb5c2401671df545a1cd8b315f66f86463 Модуль:Uses Wikidata 828 303 768 767 2024-08-26T16:46:15Z DuOfOrl 5 1 версия импортирована Scribunto text/plain local p = {} local function incat( name, label, dot ) local incat = '' if not dot then dot = '' end local pincat = mw.site.stats.pagesInCategory( name, all ) if pincat ~= 0 then incat = "[[:К:" .. name .. "|" .. label .. tostring( pincat ) .. "]]" .. dot end return incat end local function trackingcats(p_num) local result = incat("ВП:" .. p_num .. ":використовується", "'''U:'''", "•") .. incat("ВП:" .. p_num .. ":відсутня", "'''<s>U:'''", "</s>•") .. incat("Вікідані:" .. p_num .. ":відсутня", "'''<s>D:'''", "</s>•") .. incat("Вікідані:" .. p_num .. ":відрізняється", "'''↑↓:'''") if result ~= "" then return "[<span></span>" .. result .. "]" else return "" end end function p.usesProperty(frame) local parent = frame.getParent(frame) local result = '' local ii = 1 while true do local p_num = "" if parent.args[ii] or frame.args[ii] then p_num = mw.text.trim(string.upper(parent.args[ii] or frame.args[ii])) end if p_num ~= "" then local label = mw.wikibase.label(p_num) or "БЕЗ НАЗВИ" result = result .. "<li><b><i>[[d:Property:" .. p_num .. "|<small>" .. p_num .. "</small>:" .. label .. "]]</i></b> {[[d:Property talk:" .. p_num .. "|обс]]•[[d:Special:WhatLinksHere/Property:" .. p_num .. "|исп]]}" .. trackingcats(p_num) .. "</li>" ii = ii + 1 else break end end return result end return p 8a066acc434e0611d04134bb82a5fdd9d4fb5f9f Шаблон:Политик/doc 10 304 770 769 2024-08-26T16:46:16Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki {{docpage}} {{OnLua|CategoryForProfession}} {{Установлена проверка на неизвестные параметры}} {{Uses Wikidata|p18|p19|p20|p22|p25|p27|p40|p102|p106|p109|p140|p166|p512|p569|p570|p856|p1142|p1559}} Этот [[Википедия:Шаблоны-карточки|шаблон-карточка]] предназначен для статей о политиках. Для государственных деятелей существует шаблон {{t|Государственный деятель}}. Внимание, шаблон поддерживает загрузку дат смерти и рождения через [[ВП:Викиданные|Викиданные]]. Не заполняйте в шаблоне эти поля, если есть возможность использовать wikidata. ''Отметим, что большинство полей автоматически загружают информации из [[ВП:Викиданные|Викиданных]].'' Категории профессий по алфавиту и по странам добавляются автоматически на основе информации из викиданных. В случае если персоналию не следует добавлять в категорию, то существует параметр <code>без категорий=</code> в которым следует перечислить названия исключаемых категорий через точку с запятой. Пример использования — [[Special:Diff/70059213/70085957]]. Если есть только год рождения/смерти, так и пишите только цифры года. {{Старый-новый стиль,примечание}} == Заготовка для копирования == {{Заготовка шаблона}} == Пример использования == {{Пример шаблона}} == Отслеживающие категории == В служебных целях используется ряд скрытых отслеживающих категорий: {{categorytree|Отслеживающие категории:Шаблон:Политик|категории|0|title=}} == TemplateData == <templatedata> { "params": { "nocat": { "type": "boolean" }, "from": { "type": "line" }, "имя": { "aliases": [ "Имя" ], "label": "имя", "description": "имя персоны", "type": "line", "example": "Джон Доу" }, "оригинал имени": { "aliases": [ "Оригинал имени" ], "label": "оригинал имени", "description": "имя персоны на языке оригинала, обёрнутое в шаблон серии {{t|lang-en}}", "example": "{{lang-en|John Doe}}", "type": "string" }, "изображение": { "aliases": [ "Изображение" ], "label": "изображение", "description": "изображение персоны (P18)", "example": "example.jpg", "type": "wiki-file-name" }, "ширина": { "aliases": [ "Ширина" ], "label": "ширина", "type": "number", "description": "размер изображения" }, "описание изображения": { "aliases": [ "Описание изображения" ], "label": "описание изображения", "description": "должно характеризовать портрет", "type": "string" }, "имя при рождении": { "aliases": [ "Имя при рождении" ], "label": "имя при рождении", "description": "имя при рождении, если было изменено", "type": "string" }, "псевдонимы": { "aliases": [ "Псевдонимы" ], "label": "псевдонимы", "type": "string" }, "дата рождения": { "aliases": [ "Дата рождения" ], "label": "дата рождения", "type": "date", "description": "дд.мм.гггг (P569)", "example": "02.01.1960" }, "дата смерти": { "aliases": [ "Дата смерти" ], "label": "дата смерти", "type": "date", "description": "дд.мм.гггг (P570)", "example": "02.01.2000" }, "место рождения": { "aliases": [ "Место рождения" ], "label": "место рождения", "description": "место рождения (P19)", "type": "string", "example": "{{МестоРождения|Лондон}}", "autovalue": "{{МестоРождения|}}" }, "место смерти": { "aliases": [ "Место смерти" ], "label": "место смерти", "description": "место смерти (P20)", "type": "string", "example": "{{МестоСмерти|Москва}}", "autovalue": "{{МестоСмерти|}}" }, "гражданство": { "aliases": [ "Гражданство", "страна", "подданство" ], "label": "гражданство", "description": "гражданство (P27)", "type": "string", "example": "[[Великобритания]], [[Россия]]" }, "род деятельности": { "aliases": [ "Род деятельности" ], "label": "род деятельности", "description": "род деятельности (P106)", "type": "string", "example": "[[политик]], [[журналист]], [[издатель]]" }, "образование": { "aliases": [ "Образование", "альма-матер" ], "label": "образование", "description": "оконченное высшее учебное заведение (P69)", "type": "string", "example": "[[Московский государственный университет]]" }, "учёная степень": { "aliases": [ "Учёная степень" ], "label": "учёная степень", "type": "string", "description": "учёная степень (P512)", "example": "{{Учёная степень|доктор|экономических наук}}", "autovalue": "{{Учёная степень||}}" }, "вероисповедание": { "aliases": [ "Вероисповедание" ], "label": "вероисповедание", "type": "string", "description": "вероисповедание персоны", "example": "[[католицизм]]" }, "партия": { "aliases": [ "Партия" ], "label": "партия", "type": "string", "description": "партии и организации", "example": "[[КПСС]], [[Партия любителей пива]]" }, "основные идеи": { "aliases": [ "Основные идеи" ], "label": "основные идеи", "type": "string", "description": "политические взгляды и основные идеи (P1142)", "example": "[[коммунизм]], [[национализм]]" }, "отец": { "aliases": [ "Отец" ], "label": "отец", "description": "отец (P22)", "type": "string" }, "мать": { "aliases": [ "Мать" ], "label": "мать", "description": "мать (P25)", "type": "string" }, "супруг": { "aliases": [ "Супруг" ], "label": "супруг", "description": "супруг (P26)", "type": "string" }, "супруга": { "aliases": [ "Супруга" ], "label": "супруга", "description": "супруга (P26)", "type": "string" }, "дети": { "aliases": [ "Дети" ], "label": "дети", "description": "дети (P40)", "type": "string" }, "награды": { "aliases": [ "Награды", "награды и премии" ], "label": "награды", "description": "ордена, медали и тому подобное; для них есть специальные шаблоны (P166)", "type": "string", "example": "{{ряд | {{Орден Ленина}} | {{Орден Октябрьской Революции}} | {{Орден Красного Знамени}} }}" }, "автограф": { "aliases": [ "Автограф" ], "label": "автограф", "type": "wiki-file-name", "description": "отсканированная подпись персоны (P109)" }, "ширина автографа": { "aliases": [ "Ширина автографа" ], "label": "ширина автографа", "type": "number" }, "сайт": { "aliases": [ "Сайт" ], "label": "сайт", "type": "url", "description": "официальный сайт (P856)", "example": "example.com" }, "викисклад": { "aliases": [ "Викисклад" ], "label": "викисклад", "description": "название категории на Викискладе (P373)", "deprecated": true, "type": "line" }, "учёное звание": { "aliases": [ "Учёное звание" ], "label": "учёное звание", "type": "string", "description": "учёное звание", "example": "{{Учёное звание||0}}", "autovalue": "{{Учёное звание||}}" } }, "description": "Шаблон-карточка для статей о политиках.", "paramOrder": [ "имя", "оригинал имени", "изображение", "ширина", "описание изображения", "имя при рождении", "псевдонимы", "дата рождения", "место рождения", "дата смерти", "место смерти", "гражданство", "род деятельности", "образование", "учёная степень", "учёное звание", "вероисповедание", "партия", "основные идеи", "отец", "мать", "супруг", "супруга", "дети", "награды", "автограф", "ширина автографа", "сайт", "викисклад", "nocat", "from" ], "format": "block" } </templatedata> <includeonly> [[Категория:Шаблоны-карточки:Личности]] [[Категория:Шаблоны-карточки:Политика]] </includeonly> 20627691b0800f1de81471e82cb15ed1027bfbd3 Шаблон:Categorytree 10 305 772 771 2024-08-26T16:46:16Z DuOfOrl 5 1 версия импортирована wikitext text/x-wiki #REDIRECT [[Шаблон:Дерево категорий]] dbb44c74e7e2d0a61716eb7c903a7ecef6d38d15 Шаблон:Политик 10 259 773 680 2024-08-26T16:49:08Z DuOfOrl 5 wikitext text/x-wiki {{Карточка |имя = Политик |from = {{{from|}}} |стиль_вверху = background:#eaecf0; |стиль_меток = min-width:9em; |стиль_внизу = background:#eaecf0; |вверху = {{карточка/имя|{{{Имя|{{{имя|}}}}}}|from={{{from|}}}}} |вверху2 = {{{Оригинал имени|}}} |изображение = {{Карточка/изображение|{{{Изображение|{{{изображение|}}}}}}|size={{{Ширина|}}}|caption={{{Описание изображения|{{{описание изображения|}}}}}}}} |метка1 = Имя при рождении |текст1 = {{{Имя при рождении|}}} |метка2 = Псевдонимы |текст2 = {{{Псевдонимы|}}} |метка3 = Дата рождения |текст3 = {{Персона/Дата|Рождения|{{{Дата рождения|{{{дата рождения|}}}}}}|{{{Дата смерти|{{{дата смерти|}}}}}}}} |метка4 = Место рождения |текст4 = {{{Место рождения|{{{место рождения|}}}}}} |метка5 = Дата смерти |текст5 = {{Персона/Дата|Смерти|{{{Дата смерти|{{{дата смерти|}}}}}}|{{{Дата рождения|{{{дата рождения|}}}}}}}} |метка6 = Место смерти |текст6 = {{{Место смерти|{{{место смерти|}}}}}} |метка7 = Гражданство |текст7 = {{{Гражданство|{{{гражданство|}}}}}} |метка8 = Род деятельности |текст8 = {{{Род деятельности|{{{род деятельности|}}}}}} |метка9 = Образование |текст9 = {{{Образование|}}} |метка10 = Учёная степень |текст10 = {{{Учёная степень|}}} |метка11 = Учёное звание |текст11 = {{{Учёное звание|}}} |метка12 = Вероисповедание |текст12 = {{{Вероисповедание|}}} |метка13 = Партия |текст13 = {{{Партия|}}} |метка14 = Основные идеи |текст14 = {{{Основные идеи|}}} |метка15 = Отец |текст15 = {{{Отец|}}} |метка16 = Мать |текст16 = {{{Мать|}}} |метка17 = Супруг(а) |текст17 = {{#if: {{{Супруга|}}} | {{{Супруга|}}} | {{{Супруг|}}} }} |метка18 = Дети |текст18 = {{{Дети|}}} |метка19 = Награды |текст19 = {{{Награды|}}} |метка20 = Автограф |текст20 = {{#if:{{{Автограф|}}}|[[Файл:{{{Автограф|}}}|{{#if:{{{Ширина автографа|}}}|{{{Ширина автографа}}}|143px}}]]}} |внизу = {{{Сайт|}}} |внизу2 = }}{{#if:{{NAMESPACE}}{{{nocat|}}}||<!-- -->[[Категория:Персоналии по алфавиту]]<!-- -->[[Категория:Политики по алфавиту]]<!-- -->}}<noinclude>{{doc}}</noinclude> 81154b03594f472ec9e6b56503eb402ed4fc040e Шаблон:Персона/Дата 10 306 774 2024-08-26T16:50:52Z DuOfOrl 5 Новая страница: «<includeonly>{{#switch:{{{1}}} |Рождения={{#if:{{{2|}}}|{{#invoke:Infocards|dateOfBirth|{{{2|}}}|{{{3|}}}|nocat={{{nopersoncat|}}}{{NAMESPACE}}}}}} |Смерти={{#invoke:Infocards|dateOfDeath|{{{3|}}}|{{{2|}}}|nocat={{{nopersoncat|}}}{{NAMESPACE}}}} }}</includeonly><noinclude>{{doc}}</noinclude>» wikitext text/x-wiki <includeonly>{{#switch:{{{1}}} |Рождения={{#if:{{{2|}}}|{{#invoke:Infocards|dateOfBirth|{{{2|}}}|{{{3|}}}|nocat={{{nopersoncat|}}}{{NAMESPACE}}}}}} |Смерти={{#invoke:Infocards|dateOfDeath|{{{3|}}}|{{{2|}}}|nocat={{{nopersoncat|}}}{{NAMESPACE}}}} }}</includeonly><noinclude>{{doc}}</noinclude> f8ca2c197521be2ab776e6f0791ec503e7f3206c